2013-01-17 19 views
18

Sono un novizio a R. Ho una lista t1 in R che assomigliaCome estrarre elementi di lista di liste

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

Ho bisogno di ottenere un elenco unico di primi elementi in un vettore per esempio [ "a", "b"] da questo vettore t1. Come posso fare questo?

+2

si prega di fornire un esempio riproducibile, ad es. usando 'dput'. –

risposta

16

rapply offre ancora un'altra opzione:

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

Carino e conciso. Mi piace. –

+0

Grazie Matt, davvero molto conciso! – rlpatrao

+1

FWIW, puoi usare 'tail()' invece di 'head()' per ottenere ogni elemento finale, invece del primo. – user1092247

13

Vorrei utilizzare do.call e rbind per concatenare l'elenco in un data.frame. Quindi è possibile utilizzare unique sulla prima colonna per ottenere gli oggetti unici (utilizzando l'esempio dato da @AR):

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

questo è bello, ho iniziato a usare le funzioni * apply poco tempo fa e continuo a ignorarle. –

+0

le funzioni apply funzionano davvero con il tipo di matrice o con i dati di lista e sono un po 'le persone che iniziano a utilizzare R per trovare scomode da usare. Consiglio vivamente di provare ad aggiungerli al tuo arsenale, può offrire soluzioni molto efficienti e brevi. –

+0

Grazie, è un'ottima risposta. –

16

Un altro modo è quello di utilizzare 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" 
+0

+1 per l'uso di un elenco, penso che dipenda meno dalla forma esatta dell'elenco a più livelli rispetto alla mia soluzione. –

+0

sì, ha delle limitazioni :) l'esempio dato da @rlpatrao non dice nulla a riguardo, ma hai ragione. –

+0

Grazie molte persone, in realtà questo funziona bene per me. Ho lo stesso numero di colonne. Mi piace anche la risposta di @Matthew Plourde, per la sua pura concisione! – rlpatrao

4

ho cercato di trattare la caso generale quando una o più sottoliste contengono più di un elemento.

Ad esempio:

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

si può fare qualcosa di simile:

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

Usa pacchetto rlist, vale a dire

library(rlist) 
yourlist %>>% list.map(.[1])