简体   繁体   中英

How to assign a value to a column of a df using values from a vector according to a value in another df

I am simulating the growth of a plantation.

I have to fill a df with the volume of 10 trees (one per row) on each year (columns from year 0 to year 6). I have a function from the package "growthmodels" that computes the volume of the tree for each year or creates a vector with all the values in a range set of years. I have a df with the age of each tree each year (some trees die and have to be replanted, so their age starts from zero).

Here is a simplified version of the problem:

volume <- data.frame(matrix(ncol = 6, nrow = 10))
age <- data.frame("y0" = rep(0, 10))
for (y in 2:6){
        d <- sample(1:10, 1)
        d0 <- 10-d
        age <- cbind(age, c(age[1:d, y-1] + rep(1, d), rep(0, d0)))
        names(age)[y] <- paste0("y", y-1)
}
library(growthmodels)
growth <- chapmanRichards(t=1:5, alpha=3, m=.4, k=.4, beta=1)

I found the following way to do it, but it is super super slow to execute. Imagine I have to run it for more species and 100 random cases with multiple growth speeds. Do you have suggestions?

#inputing normal growth
for (y in 2:6){
        for (t in 1:nrow(volume)) {
                volume[t,y] <- chapmanRichards(t=age[t,y], alpha=3*d, m=.4, k=.4*l, beta=1)
        }
}

I need to keep the loop for (y in 2:6) because each year the factors d and l into the chapmanRichards formula have different values.

something like this in Base-R give the same results as your loop.

apply(age,2, function(y) sapply(y,function(x) chapmanRichards(t=x, alpha=3, m=.4, k=.4, beta=1) ))

      y0        y1        y2       y3        y4       y5
 [1,]  0 0.4720002 1.1098773 1.650880 2.0600919 2.354331
 [2,]  0 0.4720002 1.1098773 1.650880 2.0600919 2.354331
 [3,]  0 0.4720002 1.1098773 1.650880 2.0600919 2.354331
 [4,]  0 0.0000000 0.4720002 1.109877 1.6508796 2.060092
 [5,]  0 0.0000000 0.4720002 0.000000 0.4720002 1.109877
 [6,]  0 0.0000000 0.4720002 0.000000 0.4720002 1.109877
 [7,]  0 0.0000000 0.4720002 0.000000 0.4720002 0.000000
 [8,]  0 0.0000000 0.0000000 0.000000 0.4720002 0.000000
 [9,]  0 0.0000000 0.0000000 0.000000 0.0000000 0.000000
[10,]  0 0.0000000 0.0000000 0.000000 0.0000000 0.000000

Edit : to address your comment:

you could achieve this with

rbind(
    apply(age[1:3,],2, chapmanRichards, alpha=3, m=.4, k=.4, beta=1),
    apply(age[4:6,],2, chapmanRichards, alpha=3, m=.4, k=.4*7, beta=1),
    apply(age[7:10,],2, chapmanRichards, alpha=3, m=.4, k=0, beta=1)
)

Update to the latest comment:

t(
cbind(
    apply(age[1:3,],1, chapmanRichards, alpha=3, m=.4, k=.4, beta=1),
    apply(age[4:6,],1, chapmanRichards, alpha=3, m=.4, k=.4*7, beta=1),
    apply(age[7:10,],1, chapmanRichards, alpha=3, m=.4, k=0, beta=1)
)
)

   y0        y1       y2        y3       y4        y5
1   0 0.4720002 1.109877 1.6508796 2.060092 2.3543308
2   0 0.4720002 0.000000 0.4720002 0.000000 0.4720002
3   0 0.4720002 0.000000 0.4720002 0.000000 0.4720002
4   0 0.0000000 0.000000 2.7021553 0.000000 2.7021553
5   0 0.0000000 0.000000 0.0000000 0.000000 2.7021553
6   0 0.0000000 0.000000 0.0000000 0.000000 2.7021553
7   0 0.0000000 0.000000 0.0000000 0.000000 0.0000000
8   0 0.0000000 0.000000 0.0000000 0.000000 0.0000000
9   0 0.0000000 0.000000 0.0000000 0.000000 0.0000000
10  0 0.0000000 0.000000 0.0000000 0.000000 0.0000000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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