How to extract elements from list of lists
Asked Answered
W

7

26

I am a newbie to R. I have a list t1 in R which looks like

[[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"

I need to get a unique list of first elements into a vector i.e ["a", "b"] from this vector t1. How can I do this?

Welfarism answered 17/1, 2013 at 10:3 Comment(1)
please provide a reproducible example, e.g. using dput.Connect
I
21

rapply offers yet another option:

unique(rapply(t1, function(x) head(x, 1)))
Ingleside answered 17/1, 2013 at 12:8 Comment(1)
FWIW, you can use tail() instead of head() to get each final element, instead of the first.Ryan
A
20

Another way is to use 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"
Armagnac answered 17/1, 2013 at 10:9 Comment(3)
+1 for using unlist, I think it depends less on the exact shape of the multi-tier list than my solution does.Connect
yes it has that limitations :) the example given by @Welfarism doesn't say anything about that, but you are right.Armagnac
Thanks much folks,actually this works well for me. I have equal number of columns. I like @Matthew Plourde's answer also, for its sheer conciseness !Welfarism
C
15

I would use do.call and rbind to concatenate the list into a data.frame. Then you can use unique on the first column to get the unique items (using the example given by @A.R.):

spam = do.call("rbind", lapply(t1, "[[", 1))
> spam
     [,1] [,2]      
[1,] "a"  "control"                                                         
[2,] "b"  "disease1" 
> unique(spam[,1])
[1] "a" "b"
Connect answered 17/1, 2013 at 10:7 Comment(2)
this is nice, I started using the *apply functions a short time ago and I keep ignoring them.Armagnac
the apply functions work really with array type or list data, and are something a lot of people that start using R find uncomfortable to use. I would really recommend trying to add them to your arsenal, it can yield very efficient and short solutions.Connect
T
5

I tried to treat the general case when one or more of the sublists contain more than one element.

For example:

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"))
)

You can do something like this :

 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"   
Telestich answered 17/1, 2013 at 10:29 Comment(0)
K
5

As an update in 2020, this is done easily and intuitively with purrr. Using @Gago-Silva's test list:

library(purrr)
t1 %>% flatten() %>% map(1) %>% as_vector()

Sublists are flattened to character vectors, element 1 is extracted from these and this list of one-element character vectors converted to one vector.

Also note that you can get a tibble back directly from the list of lists with

t1 %>% flatten_dfc()
Kelle answered 1/5, 2020 at 23:44 Comment(0)
I
4

Use package rlist, i.e.

library(rlist)
yourlist %>>% list.map(.[1])
Inveigle answered 16/11, 2017 at 17:25 Comment(0)
A
3

Using base R:

t1 <- list(list("a", "control"), list("a", "disease"), list("b", "control"))
id <- sapply(t1, function(x) {x[[1]]})
unique(id)
Anent answered 6/1, 2022 at 16:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.