从文本文件中读取〜5x10 ^ 6个数字值在我的机器上相对较慢(几秒钟,我读了几个这样的文件),即使使用scan(..., what="numeric", nmax=5000)
或类似的技巧。为这类任务尝试Rcpp
包装器是否值得(例如Armadillo
有一些实用程序来读取文本文件)?
或者,由于预期的接口开销,我是否会浪费我的时间在性能上几乎没有收获?我不确定目前是什么限制了速度(内在的机器性能,或者其他?)这是我每天重复多次的任务,通常,文件格式总是相同的,1000列,大约5000行。
如果需要,这是一个可以播放的示例文件。
nr <- 5000
nc <- 1000
m <- matrix(round(rnorm(nr*nc),3),nr=nr)
cat(m[1, -1], "\n", file = "test.txt") # first line is shorter
write.table(m[-1, ], file = "test.txt", append=TRUE,
row.names = FALSE, col.names = FALSE)
更新:我使用Armadillo尝试read.csv.sql
和load("test.txt", arma::raw_ascii)
,两者都比scan
解决方案慢。
答案 0 :(得分:8)
我强烈建议您在fread
的最新版本中查看data.table
。 CRAN(1.8.6)上的版本还没有fread
(在本文发布时),所以如果您从R-forge的最新源安装,您应该能够获得它。请参阅here。
答案 1 :(得分:5)
请记住,我不是R专家,但也许这个概念适用于此:通常阅读二进制文件比阅读文本文件要快得多。如果您的源文件不经常更改(例如,您在相同的数据上运行不同版本的脚本/程序),请尝试通过scan()一次读取它们并以二进制格式存储它们(手册中有一章说明导出二进制文件)。 从那以后,您可以修改程序以读取二进制输入。
@Rcpp:scan()&amp;朋友可能会调用本机实现(如fscanf()),因此通过Rcpp编写自己的文件读取函数可能无法提供巨大的性能提升。您仍然可以尝试(并针对您的特定数据进行优化)。
答案 2 :(得分:4)
Salut Baptiste,
数据输入/输出是一个很大的主题,如此之大以至于R带有自己的manual on data input/output。
R的基本功能可能很慢,因为它们非常通用。如果你知道你的格式,你可以轻松地自己写一个更快的导入适配器。如果您也了解尺寸,则只需要一次内存分配就更容易了。
编辑:作为第一个近似,我会写一个C ++十行。打开文件,读取一行,将其分解为标记,分配给vector<vector< double > >
或类似的东西。即使您对单个向量元素使用push_back()
,您也应该与scan()
竞争,即使用它。
根据Brian Kernighan本人的代码,我曾经在C ++中有一个简洁的小csv reader
类。相当通用(对于csv文件),相当强大。
然后,您可以根据需要挤压效果。
进一步编辑:这个SO question有许多针对csv阅读案例的指针,以及对Kernighan和Plauger书的引用。
答案 3 :(得分:3)
是的,你几乎肯定能创造出比read.csv
/ scan
更快的东西。但是,对于高性能文件读取,有一些现有的技巧已经让你走得更快,所以你做的任何事情都会与那些竞争。
正如Mathias所提到的,如果您的文件不经常更改,则可以通过调用save
来缓存它们,然后使用load
恢复它们。 (确保使用ascii = FALSE
,因为读取二进制文件会更快。)
其次,正如Gabor所提到的,通过将文件读入数据库然后从该数据库读入R,您通常可以获得显着的性能提升。
第三,您可以使用HadoopStreaming包来使用Hadoop的文件读取功能。
有关这些技巧的更多想法,请参阅Quickly reading very large tables as dataframes in R。