如何避免R中的循环:从列表中选择项目

JD *_*ong 31 r list vector strsplit

我可以使用循环解决这个问题,但我正在尝试在向量中思考,所以我的代码将更多R-esque.

我有一个名单.格式为firstname_lastname.我想从这个列表中删除一个只有名字的单独列表.我似乎无法理解如何做到这一点.这是一些示例数据:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
tsplit <- strsplit(t,"_")
Run Code Online (Sandbox Code Playgroud)

看起来像这样:

> tsplit
[[1]]
[1] "bob"   "smith"

[[2]]
[1] "mary" "jane"

[[3]]
[1] "jose"  "chung"

[[4]]
[1] "michael" "marx"   

[[5]]
[1] "charlie" "ivan"   
Run Code Online (Sandbox Code Playgroud)

我可以使用这样的循环得到我想要的东西:

for (i in 1:length(tsplit)){
    if (i==1) {t_out <- tsplit[[i]][1]} else{t_out <- append(t_out, tsplit[[i]][1])} 
}
Run Code Online (Sandbox Code Playgroud)

这会给我这个:

t_out
[1] "bob"     "mary"    "jose"    "michael" "charlie"
Run Code Online (Sandbox Code Playgroud)

那么我怎么能没有循环呢?

had*_*ley 43

还有一种方法:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
pieces <- strsplit(t,"_")
sapply(pieces, "[", 1)
Run Code Online (Sandbox Code Playgroud)

换句话说,最后一行提取列表中每个组件的第一个元素,然后将其简化为向量.

这是如何运作的?好吧,你需要实现另一种写作x[1]方式"["(x, 1),即有一个叫做[子集化的函数.该sapply调用适用于对原始列表的每个元素调用此函数一次,传入两个参数,即list元素和1.

这种方法优于其他方法的优点是,您可以从列表中提取多个元素,而无需重新计算拆分.例如,姓氏将是sapply(pieces, "[", 2).一旦你习惯了这个习语,它就很容易阅读.

  • R中的所有运算符都是函数 - 中缀运算符可以用前缀表示法编写.TRUE || FALSE可以写成`||`(TRUE,FALSE),[b]可以写成`[`(a,b),甚至赋值运算符a [b] < - TRUE是`[<-`( A,b,值= TRUE).R很神奇. (6认同)

小智 26

你可以用apply(或sapply)

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
f <- function(s) strsplit(s, "_")[[1]][1]
sapply(t, f)

bob_smith    mary_jane   jose_chung michael_marx charlie_ivan 

       "bob"       "mary"       "jose"    "michael"    "charlie" 
Run Code Online (Sandbox Code Playgroud)

参见:R中"应用"的简要介绍


Wil*_*ane 10

怎么样:

tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
fnames <- gsub("(_.*)$", "", tlist)
# _.* matches the underscore followed by a string of characters
# the $ anchors the search at the end of the input string
# so, underscore followed by a string of characters followed by the end of the input string

对于RegEx方法?


小智 9

关于什么:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")

sub("_.*", "", t)
Run Code Online (Sandbox Code Playgroud)


Mat*_*ker 7

我怀疑这是最优雅的解决方案,但它胜过循环:

t.df <- data.frame(tsplit)
t.df[1, ]
Run Code Online (Sandbox Code Playgroud)

将列表转换为数据框是我能让他们做我想做的事情的唯一方法.我期待着能够真正理解如何处理列表的人阅读答案.