如何从列表中提取元素?该列表本身包含多个子列表。这些子列表中也包含多个元素。

26

我是R语言的新手,我有一个在R中的列表t1,看起来像这样:

[[1]]
[[1]][[1]]
[1] "a"       "control"


[[2]]
[[2]][[1]]
[1] "a"        "disease1"


[[3]]
[[3]][[1]]
[1] "a"        "disease2"


[[4]]
[[4]][[1]]
[1] "b"       "control"


[[5]]
[[5]][[1]]
[1] "b"        "disease1"


[[6]]
[[6]][[1]]
[1] "b"        "disease2"

我需要从向量t1中获取第一个元素的唯一列表,即 ["a", "b"]。我该如何做到这一点?


4
请提供一个可重现的例子,例如使用 dput - Paul Hiemstra
7个回答

21

rapply 提供了另一种选择:

unique(rapply(t1, function(x) head(x, 1)))

简洁可爱,我喜欢它。 - Carl Witthoft
谢谢Matt,确实非常简洁! - rlpatrao
1
顺便提一下,你可以使用 tail() 而不是 head() 来获取每个最后一个元素,而不是第一个。 - rvrvrv

20

另一种方法是使用 unlist

> t1=list(list(c("a","control")),list(c("b","disease1")))
> t1
[[1]]
[[1]][[1]]
[1] "a"       "control"


[[2]]
[[2]][[1]]
[1] "b"        "disease1"

> matrix(unlist(t1),ncol=2,byrow=TRUE)
     [,1] [,2]      
[1,] "a"  "control" 
[2,] "b"  "disease1"

+1 表示使用 unlist 函数,我认为这种方法与多层列表的具体形状无关,比我的解决方案更加灵活。 - Paul Hiemstra
是的,它有这些限制 :) @rlpatrao 给出的示例没有提到这一点,但你是正确的。 - Gago-Silva
非常感谢各位,实际上这对我很有效。我有相同数量的列。我也喜欢@Matthew Plourde的答案,因为它非常简洁! - rlpatrao

15

我会使用do.callrbind将列表连接成一个data.frame。然后,你可以在第一列上使用unique来获取唯一的项目(使用@A.R.提供的示例):

spam = do.call("rbind", lapply(t1, "[[", 1))
> spam
     [,1] [,2]      
[1,] "a"  "control"                                                         
[2,] "b"  "disease1" 
> unique(spam[,1])
[1] "a" "b"

这很棒,我不久前开始使用 *apply 函数,但一直忽略它们。 - Gago-Silva
apply函数在处理数组类型或列表数据时非常有效,但很多刚开始使用R语言的人可能会觉得不太舒服。我强烈建议尝试将其加入到您的工具库中,这可以产生非常高效和简洁的解决方案。 - Paul Hiemstra
谢谢,这是一个很好的答案。 - adam.888

5

我尝试处理通用情况,当一个或多个子列表包含多个元素时。

例如:

ll <- 
        list(list(c("a","control")),
             list(c("b","disease1")),
             list(c("c","disease2"),c("c","disease2bis")), # 2 elements
             list(c("d","disease3")),
             list(c("e","disease4"))
)

你可以像这样做:

你可以像这样做:

 unlist(lapply(ll,                                 ## for each element in the big list
        function(x) 
             sapply(1:length(x),                   ## for each element in the sublist
             function(y)do.call("[[",list(x,y))))) ## retrieve x[[y]]


[1] "a"           "control"     "b"           "disease1"    "c"         
     "disease2"    "c"           "disease2bis" "d"           "disease3"   
[11] "e"           "disease4"   

5
作为2020年的更新,这可以通过purrr轻松直观地完成。使用@Gago-Silva的测试列表:
library(purrr)
t1 %>% flatten() %>% map(1) %>% as_vector()

子列表将被压缩成字符向量,从中提取元素1,并将此由一个元素字符向量组成的列表转换为一个向量。另外请注意,您可以直接从列表的列表中获得tibble。
t1 %>% flatten_dfc()

4
使用包rlist,即:
library(rlist)
yourlist %>>% list.map(.[1])

3

使用基本的R语言:

t1 <- list(list("a", "control"), list("a", "disease"), list("b", "control"))
id <- sapply(t1, function(x) {x[[1]]})
unique(id)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接