【问题标题】:Merge multiple dataframes - memory issue合并多个数据帧 - 内存问题
【发布时间】:2026-02-10 11:25:02
【问题描述】:

我有多个数据框(超过 25 个),由三列“CompanyName”、“Year”和“VariableX”组成。 “公司编号”和“年份”的组合是唯一的。我想将所有这些数据框合并到 1 个大数据框。使用列“CompanyNumber”、“Year”、“来自 df1 的变量”、“来自 df2 的变量”等。每个数据帧包含大约 80000 行。

data <-  Reduce(function(x, y) merge(x, y, all=TRUE), 
         list(df1, df2, df3, df4, df5, df6, df7, df8, df9, df10, 
         df11, df12, df13, df14, df15, df16, df17, df18, df19, df20, 
         df21, df22, df23, df24, df25))

我尝试了上面的代码,当我的数据帧少于 8 个但不适用于完整数据时,该代码有效。我收到了错误:

错误:无法分配大小为 126.7 Mb 的向量

我目前正在使用 8GB,R 64。我已经使用 gc()rm(list=ls()) 清除了 R 的内存。

有没有办法以更少的内存占用方式在 R 中合并这些数据帧?

【问题讨论】:

  • 当我的数据帧少于 8 个时有效 ...检查第 8 个数据帧是否有任何不一致
  • @Parfait 或意识到如果您不指定 by 并且所有变量名称都相同,那么在合并 8 个数据框后,您将拥有一个包含 640,000 行而不是 80,000 行的数据框。

标签: r dataframe merge


【解决方案1】:

这通常是您在组合不唯一时遇到的问题。这会以指数方式炸毁您的数据帧。这可能是数据错误,但也可能是merge 不知道要使用哪些变量进行合并的结果。从以下带有数据框的列表开始:

CompNr <- rep(sample(1:8000),10)
Year <- rep(sample(1:10), each = 8000)

dfs <- lapply(1:25,function(i){
  out <- data.frame(CompNr, Year, 
                    X = rnorm(80000, mean = 10*i))
  #make it a bit more difficult for merge by rearranging the rows
  out <- out[sample(nrow(out)),] 
})

这在 6Gb 的计算机上运行没有问题:

out <- Reduce(function(x, y){
  merge(x, y, by = c("CompNr", "Year"),all=TRUE)
  }, dfs)

如果我省略了 by 参数,我会在第三次或第四次合并后耗尽内存。这是因为merge 使用两个数据帧中名称的交集作为by 变量。在这种情况下,这是数据框的所有变量,包括X。因此,对于all=TRUE,这相当于一个简单的rbind。仅在 3 次合并操作后,这将导致具有 320.000 行的数据框。您可以轻松了解内存不足的原因。

这个Reduce 解决方案仍然会给出大量关于重复名称的警告。您可以通过在合并之前重命名变量来解决这个问题,或者自己手动写出 reduce 操作并处理其中的名称。例如,使用suffixes 参数:

memorymerge <- function(x, by = c("CompNr","Year"), ...){

  out <- x[[1]]
  nx <- length(x[-1])

  for(i in seq(nx) + 1){
    suff <- c("",paste0(".",i))
    out <- merge(out,
                 x[[i]],
                 by = by,
                 suffixes = suff,
                 ...
                 )
  }
  return(out)
}

这会进行合并并给出以下结果:

> out <- memorymerge(dfs, all = TRUE)
> str(out)
'data.frame':   80000 obs. of  27 variables:
 $ CompNr: int  1 1 1 1 1 1 1 1 1 1 ...
 $ Year  : int  1 10 2 3 4 5 6 7 8 9 ...
 $ X     : num  10.23 9.18 10.51 11.39 10.4 ...
 $ X.2   : num  21.3 19.2 19.4 18.9 20.8 ...
 $ X.3   : num  29.2 29.1 28.9 29.7 30.7 ...
 ...

【讨论】: