需要帮助矢量化R中的for循环

时间:2014-02-27 19:45:13

标签: r for-loop vectorization

我正在尝试从我经常使用的软件包中加速R函数,所以任何帮助矢量化下面的for循环都会非常感激!

y <- array(0, dim=c(75, 12))
samp <- function(x) x<-sample(c(0,1), 1)
y <- apply(y, c(1,2), samp)

nr <- nrow(y)
nc <- ncol(y)
rs <- rowSums(y)
p <- colSums(y)
out <- matrix(0, nrow = nr, ncol = nc)

for (i in 1:nr) {
  out[i, sample.int(nc, rs[i], prob = p)] <- 1
}

我遇到困难的问题是循环中对象'rs'的引用。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

以下是两个选项:

这个使用了一些不鼓励的<<-运算符:

lapply(1:nr, function(i) out[i, sample.int(nc, rs[i], prob = p)] <<- 1)

这个使用更传统的索引:

out[do.call('rbind',sapply(1:nr, function(i) cbind(i,sample.int(nc, rs[i], prob = p))))] <- 1

我想您也可以使用Vectorize对您的函数执行隐式mapply

z <- Vectorize(sample.int, vectorize.args='size')(nc, rs, prob=p)
out[cbind(rep(1:length(z), sapply(z, length)), unlist(z))] <- 1

但我认为这不一定更清洁。

事实上,@ Roland是正确的,所有这些都比仅仅for循环慢:

> microbenchmark(op(), t1(), t2(), t3())
Unit: microseconds
 expr     min       lq   median       uq      max neval
 op() 494.970 513.8290 521.7195 532.3040 1902.898   100
 t1() 591.962 602.1615 609.4745 617.5570 2369.385   100
 t2() 734.756 754.7700 764.3925 782.4825 2205.421   100
 t3() 642.383 672.9815 711.4700 763.8150 2283.169   100

是的,无益的混淆!