我可以解决这种循环使用,但是我努力想在矢量的所以我的代码将更R式的。

我有一个名单的名字。该格式是firstname_lastname.我想摆脱这个名单的单独列表,只有第一名。我似乎无法得到我的心围绕如何做到这一点。这里是一些例子的数据:

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

这看起来是这样的:

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

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

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

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

[[5]]
[1] "charlie" "ivan"   

我能拿出来什么我要采用的循环,是这样的:

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

这会给我这样的:

t_out
[1] "bob"     "mary"    "jose"    "michael" "charlie"

所以我怎么可以这样做不循环?

有帮助吗?

解决方案

可以使用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" 

请参阅:简要介绍到“应用”中的R

其他提示

和多一个的方法:

t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
pieces <- strsplit(t,"_")
sapply(pieces, "[", 1)

在的话,最后一行提取列表中的每个部件的第一元件,然后将它简化到载体中。

这是如何工作的?那么,你需要认识到写作x[1]的另一种方式是"["(x, 1),即有一个函数调用[,做子集。所述sapply呼叫应用调用该函数一旦原始列表的每个元素,传递两个参数,列表元素和1

这种方法优于其它的优点是,可以提取从列表中的多个元件,而不必重新计算分裂。例如,姓氏将被sapply(pieces, "[", 2)。一旦你习惯了这个成语,它很容易阅读。

如何:

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

为正则表达式的方法?

什么:

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

sub("_.*", "", t)

我怀疑这是最好的解决方法,但它打败循环:

t.df <- data.frame(tsplit)
t.df[1, ]

转换列表,以数据帧是关于我可以让他们做我想做的唯一途径。我期待着阅读的人回答谁真正了解如何处理名单。

你几乎成功了它的 真的 是的只是一个问题

  1. 使用其中一个 *apply 功能环超过现有的名单,我经常开始 lapply 并且有时开关 sapply
  2. 添加一个匿名的功能操作的一个单元在一段时间
  3. 你已经知道这是 strsplit(string, splitterm) 和你需要奇 [[1]][1] 摘下的第一个任期的答案
  4. 只是把它放在一起,开始与一个优变namne(作为我们保持清晰的 tc 和朋友)

这给

> tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan") 
> fnames <- sapply(tlist, function(x) strsplit(x, "_")[[1]][1]) 
> fnames 
  bob_smith    mary_jane   jose_chung michael_marx charlie_ivan   
      "bob"       "mary"       "jose"    "michael"    "charlie" 
>

您可以使用unlist()

> tsplit <- unlist(strsplit(t,"_"))
> tsplit
 [1] "bob"     "smith"   "mary"    "jane"    "jose"    "chung"   "michael"
 [8] "marx"    "charlie" "ivan"   
> t_out <- tsplit[seq(1, length(tsplit), by = 2)]
> t_out
[1] "bob"     "mary"    "jose"    "michael" "charlie"

有可能是一个更好的方式来仅抽出奇数索引条目,但在任何情况下,你不会有一个循环。

和一个另一种方法,是根据brentonk的不公开示例...

tlist <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")结果 tsplit <- unlist(strsplit(tlist,"_"))结果 fnames <- tsplit[seq(1:length(tsplit))%%2 == 1]

我将使用下面的不公开() - 为基础的方法:

> t <- c("bob_smith","mary_jane","jose_chung","michael_marx","charlie_ivan")
> tsplit <- strsplit(t,"_")
> 
> x <- matrix(unlist(tsplit), 2)
> x[1,]
[1] "bob"     "mary"    "jose"    "michael" "charlie"

此方法的一大优点是,它解决了等效问题为姓氏在同一时间:

> x[2,]
[1] "smith" "jane"  "chung" "marx"  "ivan" 

缺点是,你需要肯定的是所有的名称符合firstname_lastname结构;如果任何不那么这种方法将断裂。

这在开始时给定的原始tsplit列表对象中,该命令就可以了:

unlist(lapply(tsplit,function(x) x[1]))

它提取所有列表元素的第一元素,然后转换一个列表的载体。第一Unlisting到矩阵,然后提取拳头柱也行,但你是依赖于一个事实,即所有的列表元素具有相同的长度。下面是输出:

> tsplit

[[1]]
[1] "bob"   "smith"

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

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

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

[[5]]
[1] "charlie" "ivan"   

> lapply(tsplit,function(x) x[1])

[[1]]
[1] "bob"

[[2]]
[1] "mary"

[[3]]
[1] "jose"

[[4]]
[1] "michael"

[[5]]
[1] "charlie"

> unlist(lapply(tsplit,function(x) x[1]))

[1] "bob"     "mary"    "jose"    "michael" "charlie"
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top