Home > Net >  Function to loop calculation of standard errors for model predictions
Function to loop calculation of standard errors for model predictions

Time:11-12

I am after some assistance to loop my code or create a function for my required calculations.

My data frame is as follows. All columns repeat the same value in every row except for newdat2$time, the value of which changes each row:

newdat2 <- data.frame(season = rep("Summer", 31), 
                      time = seq(0, 3, by = 0.1), 
                      temp = rep(21.79384, 31),
                      last.rain.bom = rep(4.232604, 31),
                      rain = rep(0.916501, 31),
                      wind = rep("nil", 31),
                      cloud = rep(40.20378, 31),
                      abundance = rep(117.6262, 31),
                      site = rep("Avalon", 31))

For each row of this data frame I would like to complete the below calculation. This calculation is calculating the standard errors of predictions from a fitted model, see here.

C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,time,21.8,4.23,0.917,0,0,0,40.2,4.78) # This represents covariate values of my fitted model. The value of time needs to change for each row of newdat2$time, all other values remain the same
s <- vcov(zib) # zib is my fitted model and this row of code is taking the variance covariance matrix of my fitted model. s is a matrix 27x27
newdat2$se <- sqrt(t(C) %*% s %*% C) # This then calculates the standard errors for my model predictions but C must change for each row of newdat2 to reflect the change in newdat2$time

For example, the first calculation completed by the loop/function would be

C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,0,21.8,4.23,0.917,0,0,0,40.2,4.78) # 0 is the first value of newdat2$time
s <- vcov(zib) 
newdat2$se <- sqrt(t(C) %*% s %*% C)

the second calculation completed by the loop/function would be

C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,0.1,21.8,4.23,0.917,0,0,0,40.2,4.78) # 0.1 is the second value of newdat2$time
s <- vcov(zib) 
newdat2$se <- sqrt(t(C) %*% s %*% C)

the third calculation completed by the loop/function would be

C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,0.2,21.8,4.23,0.917,0,0,0,40.2,4.78) # 0.2 is the third value of newdat2$time
s <- vcov(zib) 
newdat2$se <- sqrt(t(C) %*% s %*% C)

Any assistance to loop such a calculation or create a function that would enable this would be very much appreciated.

CodePudding user response:

I don't have the data or the expected result here, but this should work:
The idea is to make all the versions of the vector C into a matrix and then do the calculation with it. You would only need the diagonal elements of the resulting answer, so I think colSums(m * s %*% m) will give the same answer, but be faster.

C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,0,21.8,4.23,0.917,0,0,0,40.2,4.78)
m <- matrix(rep(C, length(newdat2$time)), ncol = length(newdat2$time))
m[19, ] <- newdat2$time
s <- vcov(zib)
newdat2$se <- sqrt(colSums(m * s %*% m))

This should be faster than looping.

CodePudding user response:

By looping, you can do it like the following:

newdat<-NULL
for(i in 1:length(newdat2$time))
{
    C = c(0,0,0,0,0,0,0.0,0,0,0,0,0,0, 0, 1,0,0,0,newdat2$time[i],21.8,4.23,0.917,0,0,0,40.2,4.78)
    s <- vcov(zib)
    newdat<-c(newdat,sqrt(t(C) %*% s %*% C))
}

Now you can just add the newdat vector to the dataframe. However, I agree with @Brian above that this one is slower as compared to the vectorised method he suggested.

  • Related