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:
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
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.
I’ve also had luck with ‘try’–any thoughts on why ‘next’ would be preferable?
I recommend using a vectorized approach, i.e., lapply, which does not bother with next but simply omits that entry by passing NULL. Cheers, Jon
helpful topic, tnx!
This is really helpful – thanks!
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?
Yup! It should. If not, please contact me and we can work it out. Cheers, Jon