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ả?
Đừ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