我有多个数据帧(超过25个),包括三列“CompanyName”,“Year”和“VariableX”。 “CompanyNumber”和“Year”的组合是独一无二的。我想将所有这些数据帧合并为一个大数据帧。使用列“CompanyNumber”,“Year”,“Variable from df1”,“Variable from 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中以较少的内存方式合并这些数据帧?
答案 0 :(得分: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
参数,我会在第3次或第4次合并后耗尽内存。这是因为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 ...
...