假設我有一個包含 100 棵樹的向量。然后我將這些樹齡分別為 5 年、10 年、15 年和 20 年,以創建今年的樹齡矩陣和未來的四個 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回圈)?這是我要迭代數千次的東西,所以速度至關重要!
謝謝!
uj5u.com熱心網友回復:
根據rbenchmark
.
這是一種依賴于這樣一個事實的方法,即采伐一棵樹不會停止時間的流逝,它只會重置時鐘。因此,我們可以將收獲視為從所有未來年齡中減去收獲年齡。
x.die <- x.mat * age.mat
x.dif <- t(apply(x.die, 1, cumsum))
age.mat2 <- age.mat - x.dif
x.die
,通過將收成乘以年齡,我們得到每次收成的年齡。下一行計算每一行的這些累積總和,最后我們從原始年齡中減去這些總和。
我假設您的“樹木不能收獲兩次”意味著我們永遠不會在一行中看到兩個 TRUE x.mat
?如果每個樹的位置不止一次收獲,我的代碼將無法正常作業。
uj5u.com熱心網友回復:
您可以使用 apply 逐行處理每個向量,然后在函式中使用一些邏輯來調整值。
應該快 4 倍左右
age.mat |>
apply(1, \(x) {
if(any(x == 0 & (which(x == 0) != length(x)))) {
x[which(x == 0):length(x)] <- (0:(length(x) - which(x == 0))) * 5
x
} else x
}) |> t()
[,1] [,2] [,3] [,4] [,5]
[1,] 101 0 5 10 15
[2,] 55 60 65 70 75
[3,] 23 28 33 0 5
[4,] 0 5 10 15 20
[5,] 23 28 33 0 5
[6,] 84 0 5 10 15
[7,] 52 57 62 0 5
[8,] 26 31 36 41 0
[9,] 114 119 124 129 0
[10,] 33 38 43 48 53
[11,] 144 149 154 159 164
[12,] 19 24 29 34 39
[13,] 43 48 53 58 63
[14,] 69 74 79 84 89
[15,] 98 103 108 113 118
[16,] 110 115 120 125 130
[17,] 8 13 18 23 28
[18,] 16 21 26 31 36
[19,] 1 6 11 16 21
[20,] 60 65 0 5 10
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/490824.html