我有非常大的表(3000 万行),我想在 R 中作为数据帧加载。 read.table()有很多方便的功能,但似乎实现中有很多逻辑会减慢速度。就我而言,我假设我提前知道列的类型,该表不包含任何列标题或行名,并且没有任何我不得不担心的病态字符。
read.table()
我知道在表格中作为列表阅读scan()可以非常快,例如:
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跑得快一点几乎没有什么好处。您的选择是:
read.table
使用vroomtidyverse 包vroom将数据从 csv/tab 分隔文件直接导入 R tibble。
vroom
使用freadindata.table将数据从 csv/制表符分隔的文件直接导入 R。
fread
data.table
使用read_tablein readr(从 2015 年 4 月起在 CRAN 上使用)。这很像fread上面的工作。链接中的 自述 文件解释了这两个函数之间的区别(readr目前声称比“慢 1.5-2 倍” data.table::fread)。
read_table
readr
data.table::fread
read.csv.rawfromiotools提供了快速读取 CSV 文件的第三个选项。
read.csv.raw
iotools
尝试在数据库而不是平面文件中存储尽可能多的数据。(作为一种更好的永久存储介质,数据以二进制格式传入和传出 R,速度更快。)read.csv.sql在sqldf包中,如JD Long 的回答中所述,将数据导入临时 SQLite 数据库,然后读取它进入R。另见:包,以及包页面RODBC的反向依赖部分。为您提供一种伪装成数据框但实际上是底层 MonetDB 的数据类型,从而提高性能。使用其功能导入数据。 允许您直接处理存储在多种类型数据库中的数据。DBIMonetDB.Rmonetdb.read.csvdplyr
read.csv.sql
sqldf
RODBC
DBI
MonetDB.R
monetdb.read.csv
dplyr
以二进制格式存储数据也有助于提高性能。使用saveRDS/ readRDS(见下文),h5或rhdf5用于 HDF5 格式的包,或write_fst/read_fst来自fst包。
saveRDS
readRDS
h5
rhdf5
write_fst
read_fst
fst
原来的答案
无论您使用 read.table 还是 scan,都可以尝试一些简单的事情。
Set nrows= 数据中的记录数 ( nmaxin scan)。
nrows
nmax
scan
确保comment.char=""关闭注释的解释。
comment.char=""
colClasses使用in显式定义每列的类read.table。
colClasses
设置multi.line=FALSE还可以提高扫描性能。
multi.line=FALSE
如果这些都不起作用,则使用其中一个分析包来确定哪些行正在减慢速度。read.table也许您可以根据结果编写一个精简版。
另一种选择是在将数据读入 R 之前对其进行过滤。
或者,如果问题是您必须定期读取它,那么使用这些方法读取一次数据,然后将数据帧保存为二进制 blob save saveRDS,那么下次你可以更快地检索它 load readRDS.
save
load