2013-08-28 64 views
1

我相对比较新data.table,并希望使用快速子设置功能来执行一些引导程序。data.table子集引导

在我的示例中,我有两列100万个随机法线,我想对某些行取样并计算两列之间的相关性。我希望在data.table网页上建议的速度提高了100倍,但也许我错过了使用data.table ...如果是的话,应该用什么方法来构建函数以便能够得到这个结果速度提升。

请参阅下面我的例子:

n <- 1e6 
set.seed(1) 
q <- data.frame(a=rnorm(n),b=rnorm(n)) 
q.dt <- data.table(q) 

df.samp <- function(){cor(q[sample(seq(n),n*0.01),])[2,1]} 
dt.samp <- function(){q.dt[sample(seq(n),n*0.01),cor(a,b)]} 

require(microbenchmark) 
microbenchmark(median(sapply(seq(100),function(y){df.samp()})), 
       median(sapply(seq(100),function(y){dt.samp()})), 
       times=100) 

Unit: milliseconds 
                expr  min  lq median  uq  max neval 
median(sapply(seq(100), function(y) {  df.samp() })) 1547.5399 1673.1460 1747.0779 1860.3371 2028.6883 100 
median(sapply(seq(100), function(y) {  dt.samp() })) 583.4724 647.0869 717.7666 764.4481 989.0562 100 
+0

我的理论:您正在看到改进采样的效果,但它是在所有样本上运行'cor()'的额外步骤,这是不可缩减的时间瓶颈。 –

+0

你的速度测试有点复杂。也许试试'samp < - sample.int(n,n/100);微基准(Q [SAMP,],q.dt [SAMP])'?我看到data.table子集的速度大约是其两倍。 – Frank

回答

1

除了@迪文的评论:

如果您分析您的代码,你会看到,最昂贵的重复函数调用那些seq(其最多需要一次)和sample

Rprof() 
median(sapply(seq(2000), function(y) {  dt.samp() })) 
Rprof(NULL) 

summaryRprof() 

# $by.self 
#     self.time self.pct total.time total.pct 
# "seq.default"   3.70 35.10  3.70  35.10 
# "sample.int"   2.84 26.94  2.84  26.94 
# "[.data.table"   1.84 17.46  10.52  99.81 
# "sample"    0.34  3.23  6.90  65.46 
# "[[.data.frame"   0.16  1.52  0.34  3.23 
# "length"    0.14  1.33  0.14  1.33 
# "cor"     0.10  0.95  0.26  2.47 
#<snip> 

更快的子集对此没有帮助。

+0

其实你可以用'sample.int(n,n * 0.01)'来消除'seq()'' – hadley