为啥 R 在使用 read.csv() 时会使用这么多内存?

Posted

技术标签:

【中文标题】为啥 R 在使用 read.csv() 时会使用这么多内存?【英文标题】:Why does R use so much memory when using read.csv()?为什么 R 在使用 read.csv() 时会使用这么多内存? 【发布时间】:2014-07-07 00:46:34 【问题描述】:

我在 linux 上运行 R(kubuntu 值得信赖)。我有一个将近 400MB 的 csv 文件,主要包含数值:

$ ls -lah combined_df.csv 
-rw-rw-r-- 1 naught101 naught101 397M Jun 10 15:25 combined_df.csv

我启动 R 和 df <- read.csv('combined_df.csv')(我得到一个 1246536x25 数据帧、3 个 int 列、3 个 logi、1 个因子和 18 个数字),然后使用来自 here 的脚本检查内存使用情况:

R> .ls.objects()
         Type  Size    Rows Columns
df data.frame 231.4 1246536      25

有点奇怪,它报告了 less 内存,但我猜这只是因为 CSV 不是数字数据的有效存储方法。

但是当我检查系统内存使用情况时,top 说 R 正在使用我可用的 8GB RAM 的 20%。和ps 报告类似:

$ ps aux|grep R
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
naught1+ 32364  5.6 20.4 1738664 1656184 pts/1 S+   09:47   2:42 /usr/lib/R/bin/exec/R

1.7Gb 的 RAM 用于 379MB 的数据集。这似乎太过分了。我知道ps isn't necessarily an accurate way of measuring memory usage,但肯定不是5倍?!为什么 R 会占用这么多内存?

此外,R 似乎在gc() 的输出中报告了类似的内容:

R> gc()
           used  (Mb) gc trigger  (Mb)  max used  (Mb)
Ncells   497414  26.6    9091084 485.6  13354239 713.2
Vcells 36995093 282.3  103130536 786.9 128783476 982.6

【问题讨论】:

当 R 从系统中获取内存时,它很少将其归还,即使它不再使用所有内存。 您是否采纳了?read.csv 中关于减少内存使用的两条建议?那里有一整节关于内存使用的明确声明:“这些函数在读取大文件时会使用惊人的内存量。”。 @JeremyS:这完全不正确,这就是垃圾收集的全部意义所在。这个问题在FAQ 7.42得到了回答。 @joran:是的! a <- read.csv('combined_df.csv', nrows=1500000, colClasses=unlist(lapply(read.csv('combined_df.csv', nrows=1), class))) 显着降低了总体内存使用量(3-4 倍)。如果您想按照这些方式发布答案,我会接受。我还将更改更改问题标题以反映问题。 gc() 并不总是像您期望的那样工作。 adv-r.had.co.nz/memory.html#gc 【参考方案1】:

正如我在上面的评论中所指出的,文档?read.csv 中有一个名为“内存使用”的部分警告说,基于read.table 的任何内容都可能使用“令人惊讶”的内存量,并建议两件事:

    使用colClasses 参数指定每列的类型,并且 指定nrows,即使是“轻度高估”。

【讨论】:

另请注意FAQ 7.42。【参考方案2】:

不确定您是否只是想了解 R 的工作原理,或者您是否想要 read.csv 的替代品,但请尝试 fread from data.table,它要快得多,而且我认为它使用的内存要少得多:

library(data.table)
dfr <- as.data.frame(fread("somecsvfile.csv"))

【讨论】:

以上是关于为啥 R 在使用 read.csv() 时会使用这么多内存?的主要内容,如果未能解决你的问题,请参考以下文章

使用 read.csv() 导入时 R 中止

R语言read csv导入后,数据变了

R 中 read.csv() 和 read.csv2() 之间的区别

试图读取存储在csv文件中的R中的推文

有没有办法使用 read.csv 从字符串值而不是 R 中的文件读取?

read.csv() 读取 data.frame OK readr::read_csv() for the same data.frame 失败,为啥?