Lindsay Veazey
Lindsay Veazey

Reputation: 135

Writing function to replace for loop in R

My for loop code iterates over each row and multiplies each predictor variable value by a coefficient value:

lpb1B$HKGLMM <- NA
for (i in 1:nrow(lpb1B)) { 
lpb1B$HKGLMM[i] <- 
(exp(-93.7016 + (2.76336 * lpb1B$Depth[i]) 
+ (-0.02  * (lpb1B$Depth[i] * lpb1B$Depth[i])) 
+ (-0.00003 * lpb1B$Dist[i]) 
+ (-0.0059 * lpb1B$Aspect[i]))) / (1 + exp(-93.7016 + (2.76336 * lpb1B$Depth[i]) 
+ (-0.02  * (lpb1B$Depth[i] * lpb1B$Depth[i])) 
+ (-0.00003 * lpb1B$Dist[i]) 
+ (-0.0059 * lpb1B$Aspect[i])))
}

Now that's some messy, lengthy code. I haven't found an example using apply() that helps me avoid this loop. Is there any way to circumvent this monster loop?

Upvotes: 2

Views: 391

Answers (2)

Ben Bolker
Ben Bolker

Reputation: 226871

You can do this much more compactly (if you like) by recasting it as a problem where you multiply a model matrix (i.e., a matrix with your data as columns) by a coefficient vector. The only potentially tricky part is matching up the order of the coefficients and the columns of the model matrix ...

Using @Phil's example:

lpb1B <- data.frame(
   Depth = sample(1:100, 20, replace = TRUE),
   Dist  = sample(1:100, 20, replace = TRUE),
   Aspect = sample(1:100, 20, replace = TRUE)
 )
 X <- model.matrix(~Dist+Aspect+Depth+I(Depth^2),lpb1B)

Check the order of columns:

 colnames(X)
 ## [1] "(Intercept)" "Dist"        "Aspect"      "Depth"       "I(Depth^2)"

Construct a matching parameter vector:

 beta <- c(-93.7016,-0.00003,-0.0059,2.76336,-0.02)

Then (using plogis(x) instead of exp(x)/(1+exp(x)) this encapsulates your loop:

 lpb1B$HKGLMM <- plogis(X %*% beta)

Upvotes: 4

Phil
Phil

Reputation: 4444

Exactly along the lines of @yannis 's answer:

lpb1B <- data.frame(
  Depth = sample(1:100, 20, replace = TRUE),
  Dist  = sample(1:100, 20, replace = TRUE),
  Aspect = sample(1:100, 20, replace = TRUE),
  stringsAsFactors = FALSE
)
lpb1B$HKGLMM <- NA

lpb1B$HKGLMM <- 
  (exp(-93.7016 + (2.76336 * lpb1B$Depth) + 
         (-0.02  * (lpb1B$Depth * lpb1B$Depth)) +
         (-0.00003 * lpb1B$Dist) + 
         (-0.0059 * lpb1B$Aspect))) / 
  (1 + exp(-93.7016 + (2.76336 * lpb1B$Depth) + 
             (-0.02  * (lpb1B$Depth * lpb1B$Depth)) + 
             (-0.00003 * lpb1B$Dist) + 
             (-0.0059 * lpb1B$Aspect)))

Upvotes: 2

Related Questions