【问题标题】:Need help vectorizing a for loop in R需要帮助矢量化 R 中的 for 循环
【发布时间】:2014-02-27 19:45:12
【问题描述】:

我正在尝试从我经常使用的包中加速 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”的引用。

有什么建议吗?

【问题讨论】:

标签: r for-loop vectorization


【解决方案1】:

这里有两个选项:

这个使用了有点气馁的&lt;&lt;- 运算符:

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

欢迎免费混淆!

【讨论】:

  • 使用 lapply&lt;&lt;- 替换 for 应该比有点不鼓励。
  • 我认为您的任何建议都不会比原始的 for 循环更快。它们只是更加模糊。
  • @Roland 我同意这一点。
猜你喜欢
  • 1970-01-01
  • 2012-06-10
  • 2020-05-03
  • 1970-01-01
  • 2013-02-27
  • 2019-02-28
  • 2014-10-03
  • 2012-12-10
相关资源
最近更新 更多