小编典典

快速读取非常大的表作为数据框

all

我有非常大的表(3000 万行),我想在 R 中作为数据帧加载。
read.table()有很多方便的功能,但似乎实现中有很多逻辑会减慢速度。就我而言,我假设我提前知道列的类型,该表不包含任何列标题或行名,并且没有任何我不得不担心的病态字符。

我知道在表格中作为列表阅读scan()可以非常快,例如:

datalist <- scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0)))

但是我将其转换为数据帧的一些尝试似乎将上述性能降低了 6 倍:

df <- as.data.frame(scan('myfile',sep='\t',list(url='',popularity=0,mintime=0,maxtime=0))))

有没有更好的方法来做到这一点?或者很可能完全不同的方法来解决这个问题?


阅读 96

收藏
2022-03-09

共1个答案

小编典典

几年后的更新

这个答案很旧,R
已经继续前进。调整read.table跑得快一点几乎没有什么好处。您的选择是:

  1. 使用vroomtidyverse 包vroom将数据从 csv/tab 分隔文件直接导入 R tibble。

  2. 使用freadindata.table将数据从 csv/制表符分隔的文件直接导入 R。

  3. 使用read_tablein readr(从 2015 年 4 月起在 CRAN 上使用)。这很像fread上面的工作。链接中的 自述 文件解释了这两个函数之间的区别(readr目前声称比“慢 1.5-2 倍” data.table::fread)。

  4. read.csv.rawfromiotools提供了快速读取 CSV 文件的第三个选项。

  5. 尝试在数据库而不是平面文件中存储尽可能多的数据。(作为一种更好的永久存储介质,数据以二进制格式传入和传出 R,速度更快。)read.csv.sqlsqldf包中,如JD Long 的回答中所述,将数据导入临时 SQLite 数据库,然后读取它进入R。另见:包,以及页面RODBC的反向依赖部分。为您提供一种伪装成数据框但实际上是底层 MonetDB 的数据类型,从而提高性能。使用其功能导入数据。 允许您直接处理存储在多种类型数据库中的数据。DBIMonetDB.Rmonetdb.read.csvdplyr

  6. 以二进制格式存储数据也有助于提高性能。使用saveRDS/ readRDS(见下文),h5rhdf5用于 HDF5 格式的包,或write_fst/read_fst来自fst包。


原来的答案

无论您使用 read.table 还是 scan,都可以尝试一些简单的事情。

  1. Set nrows= 数据中的记录数 ( nmaxin scan)。

  2. 确保comment.char=""关闭注释的解释。

  3. colClasses使用in显式定义每列的类read.table

  4. 设置multi.line=FALSE还可以提高扫描性能。

如果这些都不起作用,则使用其中一个分析包来确定哪些行正在减慢速度。read.table也许您可以根据结果编写一个精简版。

另一种选择是在将数据读入 R 之前对其进行过滤。

或者,如果问题是您必须定期读取它,那么使用这些方法读取一次数据,然后将数据帧保存为二进制 blob
save
saveRDS,那么下次你可以更快地检索它
load
readRDS.

2022-03-09