在R中逐行绑定data.frames而不创建副本

时间:2016-04-26 16:15:55

标签: r memory dataframe clone pryr

我有一个很大的data.frames列表,需要按列成对绑定,然后在被送入预测模型之前按行绑定。由于没有值会被修改,我希望最终的data.frame指向我列表中的原始data.frames。

例如:

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将具有此方向(每列唯一的data.frames由列绑定,然后由行绑定):

df1, df2
df1, df3
df2, df3

我目前正在实施此项目:

#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

如何避免复制数据但仍能达到相同的最终结果?

1 个答案:

答案 0 :(得分:0)

存储您希望的值需要R对数据帧进行一些压缩。我不认为数据帧支持压缩。

如果您想以这种方式存储数据的动机很难在内存中拟合,那么您可以尝试ff package。这将允许您以更紧凑的方式将其存储在磁盘上。 ffdf类似乎具有您需要的属性:

  

默认情况下,创建'ffdf'对象不会创建新的ff文件,而是会引用现有文件。这与data.frame不同,后者总是创建输入对象的副本,最明显的是在data.frame(matrix())中,其中输入矩阵被转换为单列。相比之下,ffdf将物理存储输入矩阵作为相同的矩阵,并虚拟地将其映射到列。

此外,ff包已针对快速访问进行了优化。

请注意,我自己没有使用过这个软件包,所以我无法保证它能解决您的问题。