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

标签 r import dataframe r-faq

我有非常大的表(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))))

有更好的方法吗?或者很可能完全不同的问题解决方法?

最佳答案

几年后的更新

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

  1. 使用 vroom 来自 tidyverse 包 vroom用于将数据从 csv/制表符分隔的文件直接导入 R tibble。参见 Hector's answer .

  2. 使用 fread data.table 用于将数据从 csv/tab 分隔文件直接导入 R。参见 mnel's answer .

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

  4. read.csv.raw 来自 iotools 为快速读取 CSV 文件提供了第三种选择。

  5. 尝试在数据库而不是平面文件中存储尽可能多的数据。 (作为更好的永久存储介质,数据以二进制格式传入和传出 R,速度更快。) read.csv.sql sqldf 包,如 JD Long's answer 中所述,将数据导入临时 SQLite 数据库,然后将其读入 R。另请参阅: RODBC 包,反向取决于 DBI package 的部分页。 MonetDB.R 为您提供一种数据类型,它伪装成数据框,但实际上是底层的 MonetDB,从而提高了性能。使用其 monetdb.read.csv 导入数据功能。 dplyr 允许您直接使用存储在多种类型数据库中的数据。

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


原答案

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

  1. 设置nrows =数据中的记录数(nmax 中的 scan)。

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

  3. 使用 colClasses 明确定义每一列的类在read.table .

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

如果这些都不起作用,则使用 profiling packages 之一以确定哪些线路正在减慢速度。也许你可以写一个精简版的read.table根据结果​​。

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

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

关于r - 快速读取非常大的表作为数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39802118/

相关文章:

包含训练集和测试集对象的 R 列表

python - 在 PySpark 中将 Spark DataFrame 从行转换为列,并将其附加到另一个 DataFrame

import - 如何加载实现相同行为的多个模块

Python:如何从两个模块导入具有相同名称的类?

javascript - 为什么当我点击按钮时我的数据文件无法更改?

python - 按绝对值排序而不更改数据

python - 使用循环在 pyspark 数据框中添加多列

r - 查找数据框中的唯一组合数和每个组合中的观察数

R flexdashboard 标签集在服务器上呈现不佳

r - 如何在函数中将新汇总列的名称传递给 data.table?