【问题标题】:Row limit for data.table in R using freadR中使用fread的data.table的行限制
【发布时间】:2013-07-09 21:27:58
【问题描述】:

我想知道使用 data.table fread 函数可以读取的行数是否有限制。我正在处理一个有 40 亿行、4 列、大约 40 GB 的表。看起来 fread 只会读取前 8.4 亿行。它没有给出任何错误,而是返回到 R 提示符,就好像它已经读取了所有数据一样!

我知道 fread 目前不适合“产品使用”,并且想了解是否有任何时间框架来实施产品发布。

我使用 data.table 的原因是,对于这种大小的文件,与将文件加载到 data.frame 等相比,它在处理数据方面非常有效。

目前,我正在尝试其他 2 个替代方案 -

1) 使用扫描并传递给 data.table

data.table(matrix(scan("file.csv",what="integer",sep=","),ncol=4))

Resulted in --
Error in scan(file, what, nmax, sep, dec, quote, skip, nlines, na.strings,  :
  too many items

2) 将文件分成多个单独的段,限制为大约。使用 Unix 拆分 5 亿行并按顺序读取它们……然后将文件按顺序循环到 fread - 有点麻烦,但似乎是唯一可行的解​​决方案。

我认为可能有一种 Rcpp 方式可以更快地做到这一点,但不确定它通常是如何实现的。

提前致谢。

【问题讨论】:

  • 确保文件的最后一行或之后的行没有异常,然后submit 报告错误或联系包管理员。
  • 你确定你有足够的内存吗?你在使用 64 位 R 吗?
  • 不,Rcpp 不一定有更快的方法,因为 Matt 已经使用 mmap。检查您的操作系统文档以了解 mmap 调用的限制。数十亿人可能正在推动它......
  • 回复:读取文件的更快方法,...根据我的经验,使用原生 KDB+ (kx.com) 可以在几分钟内完成此类任务。鉴于它是用 C 编写的(据我所知),我想知道我们是否可以在 R 中实现相同的速度...... KDB 也对文件进行 mmap,但使用了一些超级优化的代码(整个 db 二进制文件就像 1 Meg !) .有点跑题了,但还是很有趣。
  • @CauchyDistributedRV:R 之前 3.0.0 被限制为 2^31 - 1; R 3.0.0 后来通过双精度切换到索引来移动它。有关更多信息,请参阅 NEWS 文件,但我记得现在是 2^35 - 1。也就是说,您的观点仍然有效。

标签: r data.table rcpp


【解决方案1】:

我能够使用 Stackoverflow 上另一个帖子的反馈来完成此操作。这个过程非常快,使用 fread 迭代在大约 10 分钟内读取了 40 GB 的数据。由于某些限制,Foreach-dopar 在单独运行时无法按顺序将文件读​​入新的 data.tables,这些限制也在下面的页面中提到。

注意:文件列表(file_map)是通过简单的运行来准备的--

file_map <- list.files(pattern="test.$")  # Replace pattern to suit your requirement

mclapply with big objects - "serialization is too large to store in a raw vector"

引用--

collector = vector("list", length(file_map)) # more complex than normal for speed 

for(index in 1:length(file_map)) {
reduced_set <- mclapply(file_map[[index]], function(x) {
  on.exit(message(sprintf("Completed: %s", x)))
  message(sprintf("Started: '%s'", x))
  fread(x)             # <----- CHANGED THIS LINE to fread
}, mc.cores=10)
collector[[index]]= reduced_set

}

# Additional line (in place of rbind as in the URL above)

for (i in 1:length(collector)) { rbindlist(list(finalList,yourFunction(collector[[i]][[1]]))) }
# Replace yourFunction as needed, in my case it was an operation I performed on each segment and joined them with rbindlist at the end.

我的函数包括一个使用 Foreach dopar 的循环,该循环在 file_map 中指定的每个文件的多个核心上执行。这使我可以在组合文件上运行时使用 dopar 而不会遇到“序列化太大错误”。

另一个有用的帖子是 -- loading files in parallel not working with foreach + data.table

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 2015-08-23
    • 2013-10-14
    • 2015-12-30
    • 2018-02-11
    • 2020-08-23
    相关资源
    最近更新 更多