2013-02-09 70 views
9

Tôi muốn merge nhiều data.frame bằng R bằng cách sử dụng row.names, thực hiện kết nối bên ngoài đầy đủ. Đối với điều này tôi đã hy vọng để làm như sau:hợp nhất nhiều data.frame theo hàng trong R

x = as.data.frame(t(data.frame(a=10, b=13, c=14))) 
y = as.data.frame(t(data.frame(a=1, b=2))) 
z = as.data.frame(t(data.frame(a=3, b=4, c=3, d=11))) 
res = Reduce(function(a,b) merge(a,b,by="row.names",all=T), list(x,y,z)) 

Warning message: 
In merge.data.frame(a, b, by = "row.names", all = T) : 
    column name ‘Row.names’ is duplicated in the result 
> res 
    Row.names Row.names V1.x V1.y V1 
    1   1   a 10 1 NA 
    2   2   b 13 2 NA 
    3   3   c 14 NA NA 
    4   a  <NA> NA NA 3 
    5   b  <NA> NA NA 4 
    6   c  <NA> NA NA 3 
    7   d  <NA> NA NA 11 

Những gì tôi đã hy vọng để có được sẽ là:

V1 V2 V3 
    a 10 1 3 
    b 13 2 4 
    c 14 NA 3 
    d NA NA 11 

Trả lời

6

Các công trình sau đây (lên đến một số đổi tên cột cuối cùng):

res <- Reduce(function(a,b){ 
     ans <- merge(a,b,by="row.names",all=T) 
     row.names(ans) <- ans[,"Row.names"] 
     ans[,!names(ans) %in% "Row.names"] 
     }, list(x,y,z)) 

Thực tế:

> res 
    V1.x V1.y V1 
a 10 1 3 
b 13 2 4 
c 14 NA 3 
d NA NA 11 

Chuyện gì xảy ra với một hàng tham gia là một cột với rownames gốc được thêm vào trong các câu trả lời, do đó không chứa tên hàng:

> merge(x,y,by="row.names",all=T) 
    Row.names V1.x V1.y 
1   a 10 1 
2   b 13 2 
3   c 14 NA 

Hành vi này được ghi chép lại trong ?merge (dưới giá trị gia tăng)

Nếu tên hàng liên quan trùng khớp, cột thêm ký tự được gọi là Row.names được thêm ở bên trái và trong tất cả các trường hợp, kết quả có các tên hàng tự động là 'tự động'.

Khi Reduce cố gắng hợp nhất lại, nó không tìm thấy bất kỳ kết quả nào trừ khi tên được làm sạch theo cách thủ công.

2

Để liên tục, đây không phải là giải pháp sạch nhưng giải pháp thay thế, tôi chuyển đổi đối số danh sách 'Giảm' bằng cách sử dụng sapply.

Reduce(function(a,b) merge(a,b,by=0,all=T), 
         sapply(list(x,y,z),rbind))[,-c(1,2)] 
    x y.x y.y 
1 10 1 3 
2 13 2 4 
3 14 NA 3 
4 NA NA 11 
Warning message: 
In merge.data.frame(a, b, by = 0, all = T) : 
    column name ‘Row.names’ is duplicated in the result 
0

Vì một lý do nào đó, tôi đã không thành công với việc giảm. đưa ra một danh sách các data.frames (df.lst) và một danh sách các hậu tố (suff.lst) để thay đổi tên của các cột giống hệt nhau, đây là giải pháp của tôi (đó là vòng lặp, tôi biết nó xấu cho các tiêu chuẩn R, nhưng nó hoạt động) :

df.merg <- as.data.frame(df.lst[1]) 
colnames(df.merg)[-1] <- paste(colnames(df.merg)[-1],suff.lst[[1]],sep="") 
for (i in 2:length(df.lst)) { 
    df.i <- as.data.frame(df.lst[i]) 
    colnames(df.i)[-1] <- paste(colnames(df.i)[-1],suff.lst[[i]],sep="") 
    df.merg <- merge(df.merg, df.i, by.x="",by.y="", all=T) 
} 
Các vấn đề liên quan