合并耗尽内存

时间:2011-09-02 10:20:17

标签: r

我有一个如下所示的paneldata:

(只有大幅削减我的问题)

Persno 122 122 122 333 333 333 333 333 444 444 
Income 1500 1500 2000 2000 2100 2500 2500 1500 2000 2200
year 1990 1991 1992 1990 1991 1992 1993 1994 1992 1993

现在我想为每一行(PErsno)提供今年年初的经验。我使用ddply

hilf3<-ddply(data, .(Persn0), summarize, Bgwork = 1:(max(year) - min(year)))

生成如下输出:

Workexperience: 1 2 3 1 2 3 4 5 1 2

现在我想将ddply结果合并到我原来的面板数据中:

data<-(merge(data,hilf3,by.x="Persno",by.y= "Persno"))

面板数据集非常大。由于内存大小错误,代码停止。

ERRORMESSAGE:

1:在make.unique(as.character(rows))中:

达到4000Mb的总分配:请参阅help(memory.size)

我该怎么办?

4 个答案:

答案 0 :(得分:5)

重新阅读你的问题,我认为你根本不想在这里使用merge。只需对原始数据框进行排序,然后从hilf3中选择rbind Bgwork。而且,您的ddply - 调用可能会导致1:0序列,这​​很可能不是您想要的。尝试

data = data[order(data$Persno, data$year),]
hilf3 = ddply(data, .(Persno), summarize, Bgwork=(year - min(year) + 1))
stopifnot(nrow(data) == nrow(hilf3))
stopifnot(all(data$Persno == hilf3$Persno))
data$Bgwork = hilf3$Bgwork

答案 1 :(得分:4)

嗯,也许最可靠的解决方法是获得更多内存。但是,这并不总是一种选择。你能做什么在某种程度上取决于你的平台。在Windows上,检查memory.size()的结果并将其与可用RAM进行比较。如果内存大小低于RAM,则可以增加它。这不是linux上的一个选项,因为默认情况下它会显示你的所有内存。

另一个可能使问题复杂化的问题是你是否运行32位或64位系统,因为32位窗口只能根据settings寻址一定数量的RAM(2-4GB)。如果您使用的是64位Windows 7,这可以解决更多内存问题,这不是问题。

更实际的解决方案是在执行合并之前从工作区中消除所有不必要的对象。您应该运行gc()以查看您拥有和使用的内存量,以及删除任何没有更多引用的对象。就个人而言,我可能会从脚本运行您的ddply(),然后将生成的数据框保存为CSV文件,关闭工作区并重新打开它,然后再次执行合并。

最后,最糟糕的选择(但确实需要更少的内存)是创建一个新的数据帧,并使用R中的子集化命令逐个复制所需的列。我真的不推荐这个,因为它很烦人且容易出错,但是当我无法完成我的分析时,我不得不这样做(我最后投资了一台新的计算机,不久之后会有更多的RAM)。 / p>

希望这有帮助。

答案 2 :(得分:2)

如果你需要在R中合并大数据帧,一个好的选择就是以10000行为单位进行。如果要合并数据帧x和y,则循环遍历10000行的x,使用y合并(或者更确切地说使用plyr::join)并立即将这些结果附加到sigle csv文件中。将所有部分合并并写入文件后,读取该csv文件。通过正确使用逻辑索引向量和良好的rmgc调用,这非常节省内存。但它并不快。

答案 3 :(得分:0)

自从发布此问题以来,data.table包提供了数据帧的重新实现和merge函数,我发现它比R&#39; s更具内存效率默认。将默认数据帧转换为as.data.table的数据表可以避免内存问题。