2013-06-06 21 views
19

rbind không kiểm tra tên cột khi ràng buộc nhau vectơ:Làm cách nào để tôi có thể chặn các vectơ khớp với tên cột của chúng?

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 

Làm thế nào tôi có thể sản xuất ma trận này từ một số yếu tố danh sách, bảo hiểm các tên cột được kết hợp một cách chính xác trên các hàng:

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

Trả lời

11

Bạn có thể sử dụng 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))])) 

kết quả:

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

Xem câu trả lời từ @ scs76 dưới đây; giải pháp này không còn cần thiết nữa. – Ashe

+1

Điều này vẫn cần thiết nếu 'hàng' có số lượng phần tử khác nhau. – js86

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

rbind sẽ làm việc nếu bạn lần đầu tiên thay đổi mỗi phần tử của l đến một khung dữ liệu:

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

     A B 
row1 10 20 
row2 10 20 
+0

Chụp. Matthew Plourde đánh tôi với cú đấm. – SchaunW

+0

+1 đó là tất cả của bạn. –

+2

+1! và cũng lưu ý rằng điều thú vị ở đây là rằng 'rbindlist' tương đương cổ điển từ' data.table' không đưa ra câu trả lời giống như 'do.call (rbind, ...)' – agstudy

20

smartbind() sẽ phù hợp với tên cột và dung túng những người mất tích:

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

'plyr :: rbind.fill' là một giải pháp tương tự. –

11

Dường rằng trong các phiên bản hiện tại của R (tôi có phiên bản 3.3.0), rbind có khả năng kết hợp hai tập dữ liệu với cùng một cột tên ngay cả khi t hey là theo thứ tự khác nhau.

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

Tại sao không chỉ rbind(l$row1, l$row2[names(l$row1)]). Cũng hoạt động tốt cho các khung dữ liệu. Lưu ý rằng điều này sẽ hủy bỏ các cột từ l$row2 không xuất hiện trong l$row1.

Các vấn đề liên quan