Continuing a ‘for’ loop in R after an error

fruitloops

Lately, I’ve been using loops to fit a number of different models and storing the models (or their predictions) in a list (or matrix)–for instance, when bootstrapping. The problem I was running into was the for loop screeching to a halt as soon as a model kicked back an error. I wanted the function to register an error for that entry, then skip to the next one and finish off the loop.

Luckily, there’s a function called next that does just that. But I found it difficult to get the function to work, even after consulting the help file, and from searching R listservs/Stackoverflow. So I’ve provided some example code here to help those who are facing the same issue.

For the example, I fit a linear mixed effects model using lmer (just because I happen to be working with mixed models, and they throw back convergence errors more often than GLMs), then used the update function to challenge it with random draws from my dataframe. I stored the models in a list, but you could just as easily create a dummy matrix and store predictions using the predict function within the loop.

#Load nlme
library(lme4)

#Create data frame
set.seed(6)
df=data.frame(y=c(1:5+runif(5,0,1),runif(5,0,1)),
              x=rep(1:5,2),randef=rep(letters[1:2],each=5))

#Build model
mod=lmer(y~x+(1|randef),data=df)

#Create random draws from data frame to update model using a loop
set.seed(9)
df1=df[sample(nrow(df),replace=T),];df1=df1[order(df1[,"x"]),]
df2=df; df2$y=1 #Create bunk dataframe to throw back an error
df3=df[sample(nrow(df),replace=T),];df3=df3[order(df3[,"x"]),] 
df.list=list(df1,df2,df3)

#Create list to store updated models
mod.list=list()
#Update models using for loop and store in the list
for(i in seq_along(df.list)) {
  mod2=try(update(mod,data=df.list[[i]]),TRUE)
  if(isTRUE(class(mod2)=="try-error")) { next } else { mod.list[i]=mod2 } }

There has been some blow back against for loops, so an alternative is using lapply and writing a function to update the models:

#Update models using lapply and store in a list
mod.list=lapply(seq_along(df.list),function(i) {
  mod2=try(update(mod,data=df.list[[i]]),TRUE)
  if(isTRUE(class(mod2)=="try-error")) { return(NULL) } else { return(mod2) } } )

It’s a little harder to get predictions to a matrix using lapply. In this case, you could use predict within the function, then pass the list to do.call(rbind,mod.list).

Created by Pretty R at inside-R.org

Image credit: http://1.bp.blogspot.com/_PyRwUmg36Nk/TTrYwJF5ppI/AAAAAAAAAHk/tn1blPX6JYs/s1600/fruitloops-441535_jpeg.jpg

7 thoughts on “Continuing a ‘for’ loop in R after an error

  1. nickmason000 says:

    I had recently come upon the same solution. In your post the emphasis seems to be on the ‘next’ function, when in my opinion ‘try’ is really the workhorse here. You could remove ‘next’ and just have empty brackets if a try-error is not encountered and you’ll get the same result.

  2. preed3520 says:

    Can this be used for warnings messages too? For example, if I get a warning that says a model did not converge, can I use this to skip the models producing this warning in the for-loop?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s