在R中冷凝一个for循环

时间:2014-03-07 19:06:29

标签: r for-loop apply

我在R

中有以下代码
library(mvtnorm)

m = matrix(rnorm(2000000),nrow=200)
A = matrix(rnorm(40000),ncol=200)
A = A%*%t(A)
C = array(A,c(200,200,10000))

B = 10000
S = 100

postpred = array(NA,c(200,S,B))
for(i in 1:B){
    postpred[,,i] = t(rmvnorm(S,m[,i],C[,,i],method="svd"))
}

但是这段代码非常慢,因为我必须循环10,000次,同时还要从多变量法线模拟100次,mC也可以非常大。所以我想做的是能够在循环之外计算postpred。我尝试过使用apply功能,但无济于事。任何帮助或建议都非常感谢。

2 个答案:

答案 0 :(得分:1)

其他人已经指出 apply (和类似的功能)在你的情况下对你没什么帮助,而且他们是对的。

对于它的价值,我通过编译代码检查了你是否会获得性能提升。这是我用你的问题做的一个小基准(我缩小了矩阵的大小,因为否则我无法运行它们):

library(mvtnorm)

func = function()
{ 
  m = matrix(rnorm(200000),nrow=100)
  A = matrix(rnorm(10000),ncol=100)
  A = A%*%t(A)
  C = array(A,c(100,100,1000))

  B = 1000
  S = 10

  postpred = array(NA,c(1000,S,B))
  for(i in 1:B){
    postpred[,,i] = t(rmvnorm(S,m[,i],C[,,i],method="svd"))
  }
}

require(compiler)
func_compiled <- cmpfun(func)

require(microbenchmark)

microbenchmark(func_compiled(), func(), times=10) # grab a coffee, this takes some time

结果表明编译不会给你任何好处:

Unit: seconds
                 expr      min       lq   median       uq      max neval
 slow_func_compiled() 9.938632 10.12269 10.18237 10.48215 15.43299    10
          slow_func() 9.969320 10.07676 10.21916 15.44664 15.66109    10

(这可能是预期的,因为库mvtnorm应该已经编译过了)

总的来说,您只有两种方法可以优化R中的代码:

  1. 使用较小的数字(如果可以接受)
  2. 并行化您的代码

答案 1 :(得分:0)

正如Josillber所说, vectorisation 应用函数族)对你来说不会有太大作用,它确实是一个R神话显着提高速度。

建议你看看并行选项,有并行的mcapply和snow包。在这里阅读更多http://stat.ethz.ch/R-manual/R-devel/library/parallel/doc/parallel.pdf