2013-02-25 50 views
10

Tôi có một danh sách có chứa các khung dữ liệu như các yếu tố của nó trong R.Làm cách nào để hợp nhất tất cả các thành phần của danh sách trong R?

Ví dụ:

df1 <- data.frame("names"=c("John","Sam","Dave"),"age"=c(21,22,25)) 
df2 <- data.frame("names"=c("John","Sam"),"score"=c(22,25)) 
df3 <- data.frame("names"=c("John","Sam","Dave"),"country"=c("US","SA","NZ")) 
mylist <- list(df1,df2,df3) 

Có thể kết hợp tất cả các yếu tố của mylist với nhau mà không sử dụng một vòng lặp?

đầu ra của tôi mong muốn cho ví dụ này là:

names age score country 
1 John 21 22  US 
2 Sam 22 25  SA 

Danh sách trong ví dụ này chỉ có ba yếu tố; tuy nhiên, tôi đang tìm một giải pháp có thể xử lý một số phần tử tùy ý.

Trả lời

16

Bạn có thể sử dụng Reduce, một giải pháp lót:

Reduce(merge,mylist) 

    names age score country 
1 John 21 22  US 
2 Sam 22 25  SA 
7

Nhanh chóng và bẩn ví dụ:

merge(merge(df1, df2),df3) 

EDIT - Câu hỏi rất tương tự ở đây: Simultaneously merge multiple data.frames in a list

giải pháp:

merged.data.frame = Reduce(function(...) merge(..., all=F), my.list) 

Disclaimer - Tất cả tôi đã thay đổi từ @Charles câu trả lời là làm cho merge(..., all=F) thay vì T - theo cách này, nó cung cấp cho đầu ra mong muốn của bạn.

+0

Cảm ơn @alexwhan. Tôi cần phải có được cụ thể hơn. Tôi cần một giải pháp cho một danh sách với một số lượng tùy ý các yếu tố. Danh sách đầu vào của tôi có thể có số phần tử khác nhau mỗi lần thay vì ba phần tử trong ví dụ này. – user2109248

+0

Vâng, đó là những gì tôi tự hỏi – alexwhan

3

Chỉ cần để hiển thị nó có thể được thực hiện một cách khác ...

mymerge <- function(mylist) { 
    names(mylist) <- sapply(mylist, function(x) names(x)[2]) 
    ns <- unique(unlist(lapply(mylist, function(x) levels(x$names)))) 
    as.data.frame(c(list(names=ns), lapply(mylist, function(x) 
         {x[match(ns, x$names),2]}))) 
} 

> mymerge(mylist) 
    names age score country 
1 Dave 25 NA  NZ 
2 John 21 22  US 
3 Sam 22 25  SA 

Người ta có thể dễ dàng thích ứng với loại bỏ hàng với giá trị còn thiếu, hoặc có lẽ chỉ cần xóa sau đó với complete.cases.

Để hiển thị nhanh hơn, chúng tôi sẽ tạo một tập dữ liệu lớn hơn; 100 biến và 25 tên.

set.seed(5) 
vs <- paste0("V", 1:100) 
mylist <- lapply(vs, function(v) { 
    x <- data.frame(names=LETTERS[1:25], round(runif(25, 0,100))) 
    names(x)[2] <- v 
    x 
}) 

> microbenchmark(Reduce(merge, mylist), myf(mylist)) 
Unit: milliseconds 
        expr  min  lq median  uq  max 
1   myf(mylist) 12.81371 13.19746 13.36571 14.40093 33.90468 
2 Reduce(merge, mylist) 199.23714 206.28608 207.30247 208.44939 226.05980 
+0

Vâng, tôi hiếm khi bị downvoted. Không phải là tôi không đôi khi xứng đáng với nó, nhưng một bình luận sẽ được tốt đẹp. Tôi nghĩ rằng điều này khá trơn tru, và sẽ nhanh hơn 'Giảm' khi dữ liệu lớn hơn, như thể hiện trong bản chỉnh sửa. – Aaron

+0

+1 cho điểm chuẩn! Giảm rất chậm! – agstudy

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