2013-06-06 16 views
19

rbind nie sprawdza nazw kolumn podczas wiązania ze sobą wektory:Jak mogę odłączyć wektory pasujące do ich nazw kolumn?

l = list(row1 = c(10, 20), row2 = c(20, 10)) 
names(l$row1) = c("A", "B") 
names(l$row2) = c("B", "A") 
l 
$row1 
A B 
10 20 

$row2 
B A 
20 10 

rbind(l$row1, l$row2) 
     A B 
[1,] 10 20 
[2,] 20 10 

Jak mogę produkować tę macierz z wielu elementów listy, ubezpieczenia nazwy kolumn są właściwie dopasowane w poprzek rzędów:

 A B 
[1,] 10 20 
[2,] 10 20 

Odpowiedz

11

można użyć match:

l <- list(row1 = setNames(1:3, c("A", "B", "C")), 
      row2 = setNames(1:3, c("B", "C", "A")), 
      row3 = setNames(1:3, c("C", "A", "B"))) 

do.call(rbind, lapply(l, function(x) x[match(names(l[[1]]), names(x))])) 

rezultat:

 A B C 
row1 1 2 3 
row2 3 1 2 
row3 2 3 1 
+1

Zobacz odpowiedź z @ scs76 poniżej; to rozwiązanie nie jest już potrzebne. – Ashe

+1

Jest to nadal potrzebne, jeśli "wiersze" mają różną liczbę elementów. – js86

7
do.call(rbind, lapply(l, function(row) row[order(names(row))])) 
11

rbind będzie działać, jeśli najpierw zmienić każdy element l do ramki danych:

do.call("rbind", lapply(l, function(x) data.frame(as.list(x)))) 

     A B 
row1 10 20 
row2 10 20 
+0

Strzelaj. Matthew Plourde pokonał mnie na pięści. – SchaunW

+0

+1 To wszystko, co twoje. –

+2

+1! i zauważmy, że to, co jest tutaj interesujące, to klasyczny odpowiednik 'rbindlist' z' data.table' nie daje tej samej odpowiedzi co 'do.call (rbind, ...)' – agstudy

20

smartbind() będzie pasował nazwy kolumn i toleruje brakujące te:

library(gtools) 
do.call(smartbind,l) 
     A B 
row1 10 20 
row2 10 20 
+4

'plyr :: rbind.fill' jest podobnym rozwiązaniem. –

11

wydaje że w obecnych wersjach R (mam wersję 3.3.0), rbind ma możliwość połączenia dwóch zestawów danych o tych samych kolumnach nazw, nawet jeśli t hej są w innej kolejności.

df1 <- data.frame(a = c(1:5), c = c(LETTERS[1:5]),b=c(11:15)) 
    df2 <- data.frame(a = c(6:10), b = c(16:20),c=c(LETTERS[6:10])) 
    rbind(df1,df2) 
    a c b 
1 1 A 11 
2 2 B 12 
3 3 C 13 
4 4 D 14 
5 5 E 15 
6 6 F 16 
7 7 G 17 
8 8 H 18 
9 9 I 19 
10 10 J 20 
0

Dlaczego nie tylko rbind(l$row1, l$row2[names(l$row1)]). Działa również dobrze w przypadku ramek danych. Zauważ, że spowoduje to odrzucenie kolumn z l$row2, które nie pojawiają się w l$row1.