2012-05-26 137 views
4

我有一个9列data.frame(x),它有数百万行。我能够将它读入R,成功对其进行了一些修改,并且代码可以毫无问题地执行。然而,当我试着写出来使用使用write.csv时出现内存错误

write.csv(x,file=argv[2],quote=F,row.names=F) 

我得到它说

Error: cannot allocate vector of size 1.2Gb 

这是没有意义的数据已经在内存错误.csv文件,该计算完成,我想要做的就是将它写出到磁盘。另外,当我监视内存时,在此写入阶段,虚拟内存大小几乎增加了一倍。会写一个自定义的C函数来写出这个data.frame的帮助?任何建议/帮助/指针表示赞赏。

ps:我在一个64位的ubuntu机器上运行所有这些,大约有24G RAM。整体空间可能不是问题。数据大小约为10G

+2

最简单的事情就是用'append = TRUE'将它写入小文件中。另外,机器上安装的RAM总量可能是误导性指标,表明您是否会遇到内存问题,因为R经常需要特定大小的_连续_块内存。即使使用24Gb,寻找10个连续的Gb内存有时也是一个挑战。 – joran

+0

@joran说了些什么。您可以立即尝试'gc()',但这不太可能有帮助。 –

+1

您可以尝试将对象保存为.RData图像,并将其加载到新会话中。出于某种原因,它比计算后直接消耗的内存少。当我遇到内存问题时,我有时会使用这个技巧。 –

回答

9

您必须明白,R函数经常会复制参数(如果它们修改它们),因为R函数使用的函数编程范例表示函数不会更改作为参数传入的对象;因此在执行功能的过程中需要进行更改时,R会复制它们。

如果您使用内存跟踪支持构建R,则可以看到此复制正在进行中,以便进行任何您遇到问题的操作。使用airquality示例数据集,跟踪存储器使用我看到

> head(airquality) 
    Ozone Solar.R Wind Temp Month Day 
1 41  190 7.4 67  5 1 
2 36  118 8.0 72  5 2 
3 12  149 12.6 74  5 3 
4 18  313 11.5 62  5 4 
5 NA  NA 14.3 56  5 5 
6 28  NA 14.9 66  5 6 
> tracemem(airquality) 
[1] "<0x12b4f78>" 
> write.csv(airquality, "airquality.csv") 
tracemem[0x12b4f78 -> 0x1aac0d8]: as.list.data.frame as.list lapply unlist which write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0x1aabf20]: as.list.data.frame as.list lapply sapply write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0xf8ae08]: as.list.data.frame as.list lapply write.table eval eval eval.parent write.csv 
tracemem[0x12b4f78 -> 0xf8aca8]: write.table eval eval eval.parent write.csv 
tracemem[0xf8aca8 -> 0xca7fe0]: [<-.data.frame [<- write.table eval eval eval.parent write.csv 
tracemem[0xca7fe0 -> 0xcaac50]: [<-.data.frame [<- write.table eval eval eval.parent write.csv 

所以,指示正在作出的数据的6份为R准备将其写入到文件中。

显然,这是吃了你可用的RAM的24Gb;该错误表示R需要另一个 1.2Gb的RAM才能完成操作。

最简单的解决方案就是以块为单位编写文件。使用append = FALSE写出第一组数据行,然后使用append = TRUE用于后续调用write.csv()写出剩余的块。你可能需要玩弄这个来找到一个不会超过可用内存的块大小。

+3

您可能还想在第一个块之后设置'col.names = FALSE',这样您就不会在输出文件中间出现列名。 – Chase

+1

好的,似乎唯一的方法就是像@joran那样提及。将文件切成更小的块,然后以追加模式一个接一个地写出来。 – broccoli

+0

@broccoli我提到那是最简单的。如果您经常使用大型数据处理数据,那么您可以从探索** ff **或** bigmemory **软件包中受益,这些软件包旨在使处理大型数据变得更加容易。我对他们不是很熟悉,但他们可能有一些专门的功能来写入大对象到文件。 – joran

相关问题