2016-04-26 16 views
7

Tôi có một danh sách lớn dữ liệu.frames cần phải được ràng buộc theo từng cặp theo cột và sau đó theo hàng trước khi được đưa vào mô hình dự báo. Vì không có giá trị nào sẽ được sửa đổi, tôi muốn có data.frame cuối cùng trỏ đến data.frames gốc trong danh sách của tôi.Ràng buộc dữ liệu.frames hàng-khôn ngoan trong R mà không tạo bản sao

Ví dụ:

library(pryr) 

#individual dataframes 
df1 <- data.frame(a=1:1e6+0, b=1:1e6+1) 
df2 <- data.frame(a=1:1e6+2, b=1:1e6+3) 
df3 <- data.frame(a=1:1e6+4, b=1:1e6+5) 

#each occupy 16MB 
object_size(df1) # 16 MB 
object_size(df2) # 16 MB 
object_size(df3) # 16 MB 
object_size(df1, df2, df3) # 48 MB 

#will be in a named list 
dfs <- list(df1=df1, df2=df2, df3=df3) 

#putting into list doesn't create a copy 
object_size(df1, df2, df3, dfs) #48MB 

data.frame cuối cùng sẽ có định hướng này (mỗi cặp độc đáo của data.frames ràng buộc bởi cột, sau đó cặp ràng buộc bởi hàng):

df1, df2 
df1, df3 
df2, df3 

Tôi hiện đang triển khai điều này như sau:

#generate unique df combinations 
df_names <- names(dfs) 
pairs <- combn(df_names, 2, simplify=FALSE) 

#bind dfs by columns 
combo_dfs <- lapply(pairs, function(x) cbind(dfs[[x[1]]], dfs[[x[2]]])) 

#no copies created yet 
object_size(dfs, combo_dfs) # 48MB 

#bind dfs by rows 
combo_df <- do.call(rbind, combo_dfs) 

#now data gets copied 
object_size(combo_df) # 96 MB 
object_size(dfs, combo_df) # 144 MB 

Làm cách nào để tránh sao chép dữ liệu nhưng vẫn đạt được cùng một kết thúc kết quả?

+5

Đừng nghĩ rằng bạn có thể. Trong các thao tác đầu tiên, bạn chỉ là "di chuyển" các đối tượng R từ danh sách này sang danh sách khác (một cột của một data.frame là một đối tượng R của chính nó). Bước cuối cùng liên quan đến các sáng tạo của các đối tượng mới (các cột của 'combo_df') mà * tình cờ * chứa dữ liệu của hai đối tượng hiện có. Một bản sao là cần thiết. Một vector trong R lưu trữ dữ liệu của nó * liên tục *; bạn không thể tạo một vectơ trong đó một phần của dữ liệu trỏ đến một vùng và một phần khác đến một vùng khác. – nicola

Trả lời

0

Lưu trữ các giá trị như bạn hy vọng sẽ yêu cầu R thực hiện một số thao tác nén trên khung dữ liệu. Tôi không tin rằng khung dữ liệu hỗ trợ nén.

Nếu động cơ của bạn muốn lưu trữ dữ liệu theo cách này khó lắp vào bộ nhớ, bạn có thể thử ff package. Điều này sẽ cho phép bạn lưu trữ nó một cách nhỏ gọn hơn trên đĩa. Lớp ffdf dường như có các thuộc tính bạn cần:

Theo mặc định, việc tạo một đối tượng 'ffdf' sẽ KHÔNG tạo tệp ff mới, thay vào đó các tệp hiện có được thay thế. Điều này khác với data.frame, mà luôn luôn tạo ra các bản sao của các đối tượng đầu vào, đáng chú ý nhất trong data.frame (matrix()), trong đó một ma trận đầu vào được chuyển đổi thành các cột đơn. ffdf tương phản, sẽ lưu trữ một ma trận đầu vào về mặt vật lý như cùng một ma trận và hầu như ánh xạ nó tới các cột.

Ngoài ra, gói ff được tối ưu hóa để truy cập nhanh.

Lưu ý rằng tôi đã không sử dụng gói này bản thân mình vì vậy tôi không thể đảm bảo nó sẽ giải quyết vấn đề của bạn.

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