8

在我的机器上,将 ~5x10^6 数值从文本文件读取到 R 中相对较慢(几秒钟,我读取了几个这样的文件),即使使用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)

更新:我尝试read.csv.sqlload("test.txt", arma::raw_ascii)使用了犰狳,两者都比scan解决方案慢。

4

4 回答 4

8

我强烈建议查看fread最新版本的data.table. CRAN (1.8.6) 上的版本还fread没有(在这篇文章的时候),所以如果你从 R-forge 的最新源安装,你应该能够得到它。见这里

于 2013-03-03T21:32:18.877 回答
5

向巴蒂斯特致敬,

数据输入/输出是一个巨大的话题,以至于 R 有自己的数据输入/输出手册

R 的基本功能可能很慢,因为它们非常通用。如果您知道您的格式,您可以轻松地为自己编写一个更快的导入适配器。如果你也知道你的尺寸,那就更容易了,因为你只需要一个内存分配。

编辑: 作为第一个近似值,我会写一个 C++ 十行。打开一个文件,读取一行,将其分解为标记,分配给一个vector<vector< double > >或类似的东西。即使您push_back()在单个矢量元素上使用,您也应该与scan()methinks 竞争。

我曾经有过一个csv reader基于 Brian Kernighan 自己的代码的 C++ 小课堂。相当通用(对于 csv 文件),相当强大。

然后,您可以按您认为合适的方式压缩性能。

进一步编辑:这个SO question有许多关于 csv 阅读案例的指针,以及对 Kernighan 和 Plauger 书的引用。

于 2012-01-30T21:19:27.867 回答
5

请记住,我不是 R 专家,但也许这个概念也适用于这里:通常读取二进制文件比读取文本文件快得多。如果您的源文件不经常更改(例如,您在同一数据上运行不同版本的脚本/程序),请尝试通过 scan() 读取它们一次并将它们以二进制格式存储(手册中有一个章节是关于导出二进制文件)。从那里你可以修改你的程序来读取二进制输入。

@Rcpp:scan() 和朋友可能会调用本机实现(如 fscanf()),因此通过 Rcpp 编写自己的文件读取函数可能不会提供巨大的性能提升。不过,您仍然可以尝试(并针对您的特定数据进行优化)。

于 2012-01-30T09:59:30.703 回答
3

read.csv是的,您几乎可以肯定可以创建比/更快的东西scan。然而,对于高性能文件读取,有一些现有的技巧已经让你走得更快,所以你所做的任何事情都会与这些技巧竞争。

正如 Mathias 所暗示的,如果您的文件不经常更改,那么您可以通过调用来缓存它们save,然后使用load. (确保使用ascii = FALSE,因为读取二进制文件会更快。)

其次,正如 Gabor 所提到的,您通常可以通过将文件读入数据库然后从该数据库读入 R 来获得显着的性能提升。

第三,您可以使用HadoopStreaming包来使用 Hadoop 的文件读取功能。

有关这些技术的更多想法,请参阅在 R 中快速读取非常大的表作为数据帧

于 2012-01-30T14:12:15.557 回答