4

我有一个 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:我在一个大约 24G RAM 的 64 位 ubuntu 机器上运行所有这些。整体空间可能不是问题。数据大小约10G

4

1 回答 1

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 RAM;该错误表示 R 需要另外1.2Gb 的 RAM 才能完成操作。

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

于 2012-05-26T19:17:24.967 回答