2013-06-06 1 views
19

rbind не проверяет имена столбцов при связывании вместе векторов:Как перекодировать векторы, соответствующие их именам столбцов?

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 

Как я могу производить эту матрицу из ряда элементов списка, страхуя имена столбцов правильно подобраны по строкам:

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

ответ

11

Вы можете использовать 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))])) 

результат:

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

См. Ответ от @ scs76 ниже; это решение больше не требуется. – Ashe

+1

Это все еще необходимо, если «строки» имеют разные числа элементов. – js86

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

rbind будет работать, если вы сначала изменить каждый элемент л фрейму данных:

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

     A B 
row1 10 20 
row2 10 20 
+0

Стрелять. Мэтью Пурд избил меня до удара. – SchaunW

+0

+1 это все твое. –

+2

+1! а также обратите внимание, что здесь интересно, что классический эквивалент 'rbindlist' из' data.table' не дает такого же ответа, как 'do.call (rbind, ...)' – agstudy

20

smartbind() будет соответствовать имена столбцов и мирится недостающие:

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

'plyr :: rbind.fill' - аналогичное решение. –

11

Это кажется что в текущих версиях R (у меня есть версия 3.3.0) rbind может объединять два набора данных с одинаковыми столбцами имен, даже если t они в разном порядке.

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

Почему бы не просто rbind(l$row1, l$row2[names(l$row1)]). Также хорошо работает для фреймов данных. Обратите внимание, что это отменит столбцы от l$row2, которые не отображаются в l$row1.