避免R循环,并与雪并行

问题描述:

我有一个大的循环,将花费太长时间(〜100天)。我希望能够通过雪库加快速度,但我并不擅长应用报表。这只是循环的一部分,但如果我能把这部分弄清楚,其余部分应该是直截了当的。我可以用一堆apply语句或循环,但是使用函数来获取对象'p'的应用语句将是理想的。避免R循环,并与雪并行

原始数据

dim(m1) == x x # x >>> 0 
dim(m2) == y x # y >>> 0, y > x, y > x-10 
dim(mout) == x x  
thresh == x-10 #specific to my data, actual number probably unimportant 
len(v1) == y  #each element is a random integer, min==1, max==thresh 
len(v2) == y  #each element is a random integer, min==1, max==thresh 

原始循环

p <- rep(NA,y) 
for (k in 1:y){ 
    mout <- m1 * matrix(m2[k,],x,x) 
    mout <- mout/sum(mout) 

    if (v1[k] < thresh + 1){ 
     if(v2[k] < thresh + 1){ 
      p[k] <- out[v1[k],v2[k]] 
     } 
     if(v2[k] > thresh){ 
      p[k] <- sum(mout[v1[k],(thresh+1):x]) 
     } 
    } 

    #do stuff with object 'p' 
} 
+4

的'apply'类语句的一般无效率比构建良好的循环,他们只是清洁写并且在命令提示符下处理时很有用。你可以创建一个独立的模拟数据集来测试你真正想要优化的代码吗?很难说出什么是瓶颈,什么是矢量化。向量化是您的for循环实现的巨大性能收益。 –

+0

我怎么能用库雪来并行化循环?我仍然需要一些应用功能,我并没有把自己的脑袋包裹起来。 – BML

library(snow) 
dostuff <- function(k){ 
    #contents of for-loop 
    mout <- m1 * matrix(m2[k,],x,x) 
    mout <- mout/sum(mout) 

    if (v1[k] < thresh + 1){ 
     if(v2[k] < thresh + 1){ 
      p <- out[v1[k],v2[k]] 
     } 
     if(v2[k] > thresh){ 
      p <- sum(mout[v1[k],(thresh+1):x]) 
     } 
    } 

    #etc etc 

    return(list(p, 
       other_vars)) 
} 

exports = c('m1', 
      'm2', 
      'thresh', 
      'v1', 
      'x' , 
      'v2') 
cl = makeSOCKcluster(4) 
clusterExport(cl,exports) 

loop <- as.array(1:y) 
out <- parApply(cl,loop,1,dostuff) 

p <- rep(NA,y) 
for(k in 1:y){ 
    p[k]   <- out[[k]][[1]] 
    other_vars[k] <- out[[k]][[2]] 
}