dar*_*zig 36 performance benchmarking load r
我有一些R脚本,我必须尽快在R中加载几个数据帧.这非常重要,因为读取数据是程序中最慢的部分.例如:从不同的数据帧绘图.我以sav(SPSS)格式获取数据,但我可以将其转换为建议的任何格式.不幸的是,合并数据帧不是一个选项.
什么是加载数据的最快方法?我在考虑以下几点:
read.spss.attr变量的任何自定义值(例如来自Spss导入文件的variable.labels)吗?或者这应该在一个单独的表中完成?欢迎任何其他想法.感谢您提前提出的每一个建议!
我根据你给出的答案在下面做了一个小实验,并且还添加了(24/01/2011)一个非常"hackish"但非常快速的解决方案,只从一个特殊的二进制文件中加载几个变量/列.后者似乎是我现在能想象的最快的方法,这就是为什么我编写了一个名为save的小包来处理这个功能(05/03/2011:ver.0.3).该套餐正在"重"开发,欢迎任何推荐!
在microbenchmark软件包的帮助下,我将很快发布一个具有准确基准测试结果的小插图.
dar*_*zig 39
谢谢大家的提示和答案,我做了一些总结和实验.
请参阅下面的公共数据库(匈牙利的ESS 2008)进行一些测试.该数据库有1508个案例和508个变量,因此它可能是一个中型数据.这可能是(对我而言)进行测试的一个很好的例子,但当然特殊需要需要进行足够数据的实验.
从SPSS sav文件中读取数据而不做任何修改:
> system.time(data <- read.spss('ESS_HUN_4.sav'))
user system elapsed
2.214 0.030 2.376
Run Code Online (Sandbox Code Playgroud)
使用转换后的二进制对象加载:
> save('data',file='ESS_HUN_4.Rdata')
> system.time(data.Rdata <- load('ESS_HUN_4.Rdata'))
user system elapsed
0.28 0.00 0.28
Run Code Online (Sandbox Code Playgroud)
尝试使用csv:
> write.table(data, file="ESS_HUN_4.csv")
> system.time(data.csv <- read.csv('ESS_HUN_4.csv'))
user system elapsed
1.730 0.010 1.824
Run Code Online (Sandbox Code Playgroud)
尝试使用"微调" csv加载:
> system.time(data.csv <- read.table('ESS_HUN_4.csv', comment.char="", stringsAsFactors=FALSE, sep=","))
user system elapsed
1.296 0.014 1.362
Run Code Online (Sandbox Code Playgroud)
还有包sqldf,它似乎加载csv文件更快:
> library(sqldf)
> f <- file("ESS_HUN_4.csv")
> system.time(bigdf <- sqldf("select * from f", dbname = tempfile(), file.format = list(header = T, row.names = F, sep="\t")))
user system elapsed
0.939 0.106 1.071
Run Code Online (Sandbox Code Playgroud)
并且还从在localhost上运行的MySQL数据库加载数据:
> library(RMySQL)
> con <- dbConnect(MySQL(), user='root', dbname='test', host='localhost', password='')
> dbWriteTable(con, "data", as.data.frame(data), overwrite = TRUE)
> system.time(data <- dbReadTable(con, 'data'))
user system elapsed
0.583 0.026 1.055
> query <-('SELECT * FROM data')
> system.time(data.sql <- dbGetQuery(con, query))
user system elapsed
0.270 0.020 0.473
Run Code Online (Sandbox Code Playgroud)
在这里,我认为我们应该添加两个system.time报告,因为在我们的情况下连接到数据也是重要的.如果我误解了什么,请评论.
但是让我们看看是否只查询一些变量,例如.在绘图时我们在大多数情况下不需要所有数据帧,只查询两个变量就足以创建一个很好的情节:
> query <-('SELECT c1, c19 FROM data')
> system.time(data.sql <- dbGetQuery(con, query))
user system elapsed
0.030 0.000 0.112
Run Code Online (Sandbox Code Playgroud)
这真的很棒!当然只是在加载表后dbReadTable
总结:从二进制文件中读取整个数据没什么可读的,但在某些特殊情况下,也可能只从同一个数据库表中读取几列(或其他过滤数据).
测试环境:配备低端SSD的HP 6715b笔记本电脑(AMD X2 2Ghz,4 Gb DDR2).
更新(24/01/2011):我添加了一个相当hackish但非常"创造性"的方式来加载二进制对象的几列 - 这看起来比上面检查的任何方法快得多.
请注意:代码看起来非常糟糕,但仍然非常有效:)
首先,我通过以下循环将data.frame的所有列保存到不同的二进制对象中:
attach(data)
for (i in 1:length(data)) {
save(list=names(data)[i],file=paste('ESS_HUN_4-', names(data)[i], '.Rdata', sep=''))
}
detach(data)
Run Code Online (Sandbox Code Playgroud)
然后我加载两列数据:
> system.time(load('ESS_HUN_4-c19.Rdata')) +
> system.time(load('ESS_HUN_4-c1.Rdata')) +
> system.time(data.c1_c19 <- cbind(c1, c19))
user system elapsed
0.003 0.000 0.002
Run Code Online (Sandbox Code Playgroud)
这看起来像一个"超快"的方法!:)注意:它加载速度比上面的最快(加载整个二进制对象)方法快100倍.
我已经组成了一个非常小的包(命名为:save),如果有兴趣的话,请查看github以获取更多详细信息.
更新(06/03/2011):我的小包(保存)的新版本被上传到CRAN,在该版本中可以更快地保存和加载变量 - 如果只有用户只需要可用变量的一部分数据框或列表.请参阅包源中的插图以获取详细信息或我主页上的插图,并让我介绍一些基准测试的好框图:

这箱线图显示使用的好处可以节省包只加载变量的一个子集对load和read.table或read.csv从基地,read.spss从国外或sqldf或RMySQL包.
Jor*_*eys 19
这取决于您想要做什么以及如何进一步处理数据.在任何情况下,只要您始终需要相同的数据集,从二进制R对象加载总是会更快.这里的限制速度是硬盘的速度,而不是R.二进制形式是工作空间中数据帧的内部表示,因此不再需要转换.
任何类型的文本文件都是不同的故事,因为你总是包含一个开销:每次读入文本文件时,数据都必须转换为二进制R对象.我会忘记他们.它们仅用于将数据集从一个应用程序移植到另一个应用程序.
如果您需要不同的数据部分或不同组合的不同子集,则设置MySQL后端非常有用.特别是在处理大型数据集时,在开始选择行/列之前不需要加载整个数据集这一事实可以获得相当长的时间.但这仅适用于大型数据集,因为读取二进制文件比搜索数据库要快得多.
如果数据不是太大,您可以将不同的数据帧保存在一个RData文件中,这样您就有机会简化一些事情.我经常在列表或单独的环境中有一组数据帧(另请参阅?environment一些简单示例).这允许lapply/ eapplysolutions一次处理多个数据帧.