2017-11-08 28 views
8

Powiedz, że mam N list, które wszystkie mają te same nazwy kolumn. Chcę je połączyć tak, aby uzyskać wynikową listę z tymi samymi kolumnami, ale teraz zawierającą wpisy z całej listy N. Oto MWE pokazując to, co chcę:Jak scalać listy o identycznych nazwach kolumn, aby uzyskać ich związek

ls<-list() 
ls[[1]]<-list("a"=1, 
       "b"=2) 
    ls[[2]]<-list("a"=3, 
        "b"=4) 

#how to write a one-liner that produces lsTotal, which is the union of ls[[1]] and ls[[2]]? 

lsTotal<-list("a"=c(1,3), 
       "b"=c(2,4)) 

Znalazłem thread, z których mogę korzystać Map(c, ls[[1]], ls[[2]]). Jednak napisanie go jest uciążliwe, jeśli ls jest bardzo długi. Czy jest skrót?

+1

Zauważ, że jest mniej pisania, aby zbudować przykładową listę w jednym wierszu: 'ls <- list (lista (a = 1, b = 2), lista (a = 3 , b = 4)) '. – lmo

+0

Czy elementy w podlistach są zawsze w tej samej kolejności? –

Odpowiedz

7

Jedną z opcji jest tidyverse

library(purrr) 
library(dplyr) 
transpose(ls) %>% 
     map(unlist) 

Albo użyć Map z do.call

do.call(Map, c(f=c, ls)) 
#$a 
#[1] 1 3 

#$b 
#[1] 2 4 
3

Oto prosty dwa-liner z unlist i split.

# get a named vector 
tmp <- unlist(ls) 

# split on the names 
split(unname(tmp), names(tmp)) 
$a 
[1] 1 3 

$b 
[1] 2 4 
2

Wiem, że to pytanie ma już kilka odpowiedzi, ale inną opcją jest użycie Reduce z Map zastosować Map do każdego z elementów kolejno w liście:

Reduce(function(x,y) Map(c,x,y), ls) 
#$a 
#[1] 1 3 

#$b 
#[1] 2 4 

lub na bardziej skomplikowany przykład, wyniki:

ls <- list(list(a=1, b=2), list(a=3, b=4), list(a=2,b=4), list(a=5,b=2), list(a=3,b=2)) 

#$a 
#[1] 1 3 2 5 3 

#$b 
#[1] 2 4 4 2 2 
Powiązane problemy