r - 向量化更改矩阵列的 for 循环

标签 r performance loops for-loop matrix

假设我有一个包含 100 棵树的树龄的向量。然后我将这些树老化到 future 5、10、15 和 20 年,以创建今年和 future 四个 5 年规划期的树龄矩阵。

但后来,我决定砍掉其中一些树(每个规划期仅砍伐 10 棵),记录在 T/F 值矩阵中,其中 T 被采伐而 F 未采伐(树木不能被采伐两次)。

age.vec <- sample(x = 1:150, size = 100, replace = T) # create our trees
age.mat <- cbind(age.vec, age.vec+5, age.vec + 10, age.vec + 15, age.vec + 20) # grow them up
x.mat <- matrix(data = F, nrow = 100, ncol = 5) # create the empty harvest matrix
x.mat[cbind(sample(1:100, size = 50), rep(1:5, each = 10))] <-  T # 10 trees/year harvested

那么,那一年被采伐的树的年龄变为零: age.mat[x.mat] <- 0

然后我想在接下来的时间里再次陈化采伐的树木。例如。如果一棵树在第一个规划期收获,在第二个规划期(5 年后),我希望树的年龄为 5,然后在第三个规划期(10 年后),我希望树龄为树为 10。我已在以下 for 循环中成功实现了这一点:

for (i in 2:5){ # we don't need to calculate over the first year
  age.mat[,i]<-age.mat[,i-1]+5L # add 5 to previous year
  age.mat[x.mat[,i],i] <- 0L # reset age of harvested trees to zero
}

这是有效的,但是,它笨重且缓慢。有没有办法更快地实现这个(即没有 for 循环)?它也是在函数内实现的,这意味着使用“应用”实际上会减慢速度,因此需要直接对其进行矢量化。这是我要迭代数千次的内容,因此速度至关重要!

谢谢!

最佳答案

@Jon Spring 的回答中 t(apply 的替代方法是 matrixStats::rowCumsums

library(matrixStats)

n <- 1e4L
n10 <- n/10L
age.mat <- outer(sample(150, n, TRUE), seq(0, 20, 5), "+")
x.mat <- matrix(FALSE, n, 5) # create the empty harvest matrix
# sample harvests so that no tree is harvested twice
x.mat[matrix(c(sample(n, n/2L), sample(n10:(6L*n10 - 1L)) %/% n10), n/2L)] <- TRUE

f1 <- function(age, x) {
  age[x[,1],] <- 0
  for (i in 2:5){ # we don't need to calculate over the first year
    age[,i] <- age[,i - 1] + 5L # add 5 to previous year
    age[x[,i], i] <- 0L # reset age of harvested trees to zero
  }
  age
}

f2 <- function(age, x) {
  age - rowCumsums(x*age)
}

microbenchmark::microbenchmark(f1 = f1(age.mat, x.mat),
                               f2 = f2(age.mat, x.mat),
                               check = "equal")
#> Unit: microseconds
#>  expr   min    lq     mean median     uq     max neval
#>    f1 294.4 530.2 1023.450  566.6 629.35 33222.8   100
#>    f2 135.2 263.6  334.622  284.2 307.15  4343.6   100

关于r - 向量化更改矩阵列的 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72611249/

相关文章:

mysql - 在数据库中存储标签的最佳实践?

c - 将整数拆分为两个独立的整数

python - 如果 `times` 则循环 `times is not None` 否则永远循环

r - 在 R 中相交 - 错过一个多边形

r - 按照一定的规则调整向量子集值

windows - 以编程方式清除 R 控制台

Python 嵌套循环行为

r - 如何检查字符向量是否包含字符串

c# - C# 中的代码效率

HTML5 视频 - 为用户提供播放速度选项