2012-06-21 28 views
23

Tôi đang tìm phương pháp hiệu quả (cả tài nguyên máy tính khôn ngoan và học tập/triển khai khôn ngoan) để kết hợp hai khung dữ liệu lớn hơn (kích thước> 1 triệu/300 KB RData).Các lựa chọn thay thế hiệu quả để hợp nhất cho dữ liệu lớn hơn. Khung hình R

"hợp nhất" trong cơ sở R và "tham gia" trong plyr xuất hiện để sử dụng hết bộ nhớ của tôi có hiệu quả làm hỏng hệ thống của tôi.

Ví dụ
tải test data frame

và thử

test.merged<-merge(test, test) 

hoặc

test.merged<-join(test, test, type="all") 
    -

Các bài sau đây cung cấp một danh sách các lựa chọn thay thế hợp nhất và:
How to join (merge) data frames (inner, outer, left, right)?

Sau đây cho phép kiểm tra kích thước đối tượng:
https://heuristically.wordpress.com/2010/01/04/r-memory-usage-statistics-variable/

dữ liệu được tạo ra bởi anonym

+8

sql.df hoặc data.table? –

+0

Sau khi đưa ra các câu trả lời hay dưới đây, tôi có thể tìm thấy: http://stackoverflow.com/questions/4322219/whats-the-fastest-way-to-merge-join-data-frames-in-r (mặc dù câu hỏi không phải là về df lớn nhưng về tiết kiệm mili giây, nó đã nhận được câu trả lời tương tự như dưới đây). –

Trả lời

18

đây là bắt buộc data.table dụ:

library(data.table) 

## Fix up your example data.frame so that the columns aren't all factors 
## (not necessary, but shows that data.table can now use numeric columns as keys) 
cols <- c(1:5, 7:10) 
test[cols] <- lapply(cols, FUN=function(X) as.numeric(as.character(test[[X]]))) 
test[11] <- as.logical(test[[11]]) 

## Create two data.tables with which to demonstrate a data.table merge 
dt <- data.table(test, key=names(test)) 
dt2 <- copy(dt) 
## Add to each one a unique non-keyed column 
dt$X <- seq_len(nrow(dt)) 
dt2$Y <- rev(seq_len(nrow(dt))) 

## Merge them based on the keyed columns (in both cases, all but the last) to ... 
## (1) create a new data.table 
dt3 <- dt[dt2] 
## (2) or (poss. minimizing memory usage), just add column Y from dt2 to dt 
dt[dt2,Y:=Y] 
+0

Cảm ơn câu trả lời tuyệt vời. Tôi đoán nếu bạn muốn thứ tự ban đầu duy trì bạn thêm một 1: phát triển (df) cột và sử dụng nó như là yếu tố đầu tiên của khóa? –

+0

@ EtienneLow-Décarie - Đó là một câu hỏi hay. Tôi nghĩ bạn muốn thêm một cột như vậy, nhưng ** không ** làm cho nó thành phần tử của khóa. Bằng cách đó bạn có thể sử dụng nó để sắp xếp lại dữ liệu tại bất kỳ thời điểm nào. (Nó không phải là một phần của khóa vì nó chỉ là một điểm đánh dấu đơn hàng, không phải là một biến số/nhóm có cùng ý nghĩa trong các tập dữ liệu khác nhau). –

+2

Liệu data.table có thể kết thúc nhu cầu áp dụng và plyr không !? Khá ấn tượng! –

0

Bạn phải làm việc hợp nhất trong R? Nếu không, hãy hợp nhất các tệp dữ liệu cơ bản bằng cách nối một tệp đơn giản và sau đó tải chúng vào R. (Tôi nhận thấy điều này có thể không áp dụng cho trường hợp của bạn - nhưng nếu có, nó có thể giúp bạn tiết kiệm rất nhiều đau đầu.)

+2

Nó phải được thực hiện trực tiếp trong R vì nó là một bước trong một thói quen tối ưu hóa ghi vào đĩa có lẽ sẽ là một nút cổ chai. Cảm ơn mặc dù. –

20

Dưới đây là một số timings cho data.table vs data.frame phương pháp.
Sử dụng data.table nhanh hơn rất nhiều. Về bộ nhớ, tôi có thể báo cáo không chính thức rằng hai phương pháp này rất giống nhau (trong vòng 20%) trong việc sử dụng RAM.

library(data.table) 

set.seed(1234) 
n = 1e6 

data_frame_1 = data.frame(id=paste("id_", 1:n, sep=""), 
          factor1=sample(c("A", "B", "C"), n, replace=TRUE)) 
data_frame_2 = data.frame(id=sample(data_frame_1$id), 
          value1=rnorm(n)) 

data_table_1 = data.table(data_frame_1, key="id") 
data_table_2 = data.table(data_frame_2, key="id") 

system.time(df.merged <- merge(data_frame_1, data_frame_2)) 
# user system elapsed 
# 17.983 0.189 18.063 


system.time(dt.merged <- merge(data_table_1, data_table_2)) 
# user system elapsed 
# 0.729 0.099 0.821 
Các vấn đề liên quan