2013-06-06 15 views
19

rbind non controlla i nomi di colonna quando abbinando vettori:Come posso rbindare i vettori corrispondenti ai nomi delle colonne?

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 

Come posso produrre questa matrice da un certo numero di elementi della lista, assicurando i nomi delle colonne siano correttamente abbinate tra le righe:

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

risposta

11

È possibile utilizzare 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))])) 

Il risultato:

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

Vedere la risposta da @ scs76 di seguito; questa soluzione non è più necessaria. – Ashe

+1

Questo è ancora necessario se le 'righe' hanno numeri diversi di elementi. – js86

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

rbind funzionerà se si cambia prima ogni elemento di L ad un frame di dati:

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

     A B 
row1 10 20 
row2 10 20 
+0

Spara. Matthew Plourde mi ha battuto per il pugno. – SchaunW

+0

+1 è tutto tuo. –

+2

+1! e anche notare che ciò che è interessante è che la classica equivalente 'rbindlist' da' data.table' non danno la stessa risposta 'do.call (rbind, ...)' – agstudy

20

smartbind() corrisponderà nomi delle colonne e tollera quelli mancanti:

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

'plyr :: rbind.fill' è una soluzione simile. –

11

Sembra che nelle versioni correnti di R (ho la versione 3.3.0), rbind ha la capacità di unire due set di dati con le colonne dello stesso nome anche se t hey sono in ordine diverso.

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

Perché non solo rbind(l$row1, l$row2[names(l$row1)]). Funziona bene anche per i frame di dati. Si noti che questo eliminerà le colonne da l$row2 che non compaiono in l$row1.

Problemi correlati