繁体   English   中英

R:如何矢量化代码以删除 for 循环

[英]R: how to vectorize code to remove for loop

我正在 R 中编写蒙特卡洛模拟,我需要执行 100,000 次。 我遇到了一些效率问题。 我遇到的一个关键效率问题是我在较大的 Monte Carlo for 循环中有一个 for 循环。 如果可能的话,我想尝试删除这个循环,但目前我很难过。

我有一个 dataframe 包含一个值以及一个开始和结束,它们是最终矩阵的索引。

这是一个示例代码片段:

a <- data.frame( value = c( 3, 10, 5, 8),
                 start = c(2, 3, 4, 5), 
                 end = c( 9, 10, 9, 8 ))

b <- matrix( 0, nrow = nrow(a), ncol = 10)

# this is the for loop that I would like to remove
for ( i in 1:nrow(a) ) {
  b[ i, a$start[i]:a$end[i] ]<- a$value[i]
}

感觉好像我应该能够将问题重新定义为某种类型的连接,但我一直无法取得进展。 任何帮助表示赞赏。

使用rep.intsequence和矩阵索引进行矢量化:

len <- a$end - a$start + 1
b[matrix(c(rep.int(1:nrow(a), len), sequence(len, a$start)), ncol = 2)] <- rep.int(a$value, len)

在更大的数据集上,矢量化版本的速度要快 13 倍以上:

a <- data.frame(value = sample(10, 1e5, replace = TRUE),
                start = sample(5, 1e5, replace = TRUE), 
                end = sample(6:10, 1e5, replace = TRUE))
b <- matrix(0, nrow = nrow(a), ncol = 10)

vecfill <- function(a, b) {
  len <- a$end - a$start + 1
  b[matrix(c(rep.int(1:nrow(a), len), sequence(len, a$start)), ncol = 2)] <- rep.int(a$value, len)
  return(b)
}

iterfill <- function(a, b) {
  for ( i in 1:nrow(a) ) {
    b[ i, a$start[i]:a$end[i] ]<- a$value[i]
  }
  
  return(b)
}

microbenchmark::microbenchmark(vecfill(a, b), iterfill(a, b), times = 100)
#> Unit: milliseconds
#>            expr      min        lq      mean    median       uq      max neval
#>   vecfill(a, b)  19.5291  19.99705  24.72165  21.01205  24.0373  75.8988   100
#>  iterfill(a, b) 292.6082 310.52755 330.09472 319.50020 331.3736 560.9486   100

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM