我有一个9列data.frame(x),它有数百万行。我能够将它读入R,成功地对它进行一些修改,代码执行没有问题。但是,当我尝试使用
将其写入.csv文件时write.csv(x,file=argv[2],quote=F,row.names=F)
我收到错误消息
Error: cannot allocate vector of size 1.2Gb
这没有任何意义,因为数据已经在内存中,计算已完成,而我想要做的就是将其写入磁盘。此外,在我监视内存时,在此写入阶段,此过程的虚拟内存大小几乎翻了一番。编写自定义C函数来写出这个data.frame帮助吗?任何建议/帮助/指针赞赏。
ps:我在64位ubuntu盒子中运行所有这些,大约24G RAM。整体空间可能不是问题。数据大小约为10G
答案 0 :(得分: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
因此,当R准备写入文件时,表示正在制作6份数据。
显然,你正在吃掉你可用的24Gb内存;错误说R需要另一个 1.2Gb的RAM来完成操作。
最简单的解决方案是以块的形式编写文件。使用append = FALSE
写出第一组数据,然后使用append = TRUE
对write.csv()
的后续调用写出剩余的块。您可能需要使用此方法来查找不会超出可用内存的块大小。