Exception Handling in R using Try
I was working on a project yesterday that required me to do some exception handling in R. Anyone who has tried this knows it is more difficult than necessary. Specifically, for my project, I need to catch exceptions that are raised by an R function, and if an exception is caught I need the code to process the next element in a list.
I looked at the R documentation, read the forums, and even hit up a fairly decent site that attempted to explain exception handling in R, but I just wasn't getting it...and neither were tons of other people who had been posting on the forums.
So, this is what I finally figured out. In retrospect, I guess this was kind of obvious, but at the time, it didn't seem like it.
The purpose of my code is to generate 16 models using nls. All 16 datasets are contained in one larger data.frame. Thus, I use a for loop to go through the process. The easiest way to get try to work is to create a new function that holds the code that may throw the exception. In my example code, my new function is called nonlinear_modeling. FYI: nls was what was throwing the exceptions -- due to my choice of starting values for the parameters. The "if" statement within the "for" loop provides the error handling (i.e., catches the error), and if an exception occured, then it moves the for loop to the next item in the set.
Code
#######################################################################
# Oxygen.R
#
# Author: Lyle D. Burgoon, Ph.D.
# Visiting Assistant Professor
#
# Affiliation: Gene Expression in Development and Disease Initiative
# Quantitative Biology Initiative
# Department of Biochemistry & Molecular Biology
# Center for Integrative Toxicology
# National Food Safety & Toxicology Center
# Michigan State University
#
# Version: 1.0 September 2, 2009
#
# Purpose: This code performs a generalized linear mixed model on the
# PreSens dissolved oxygen data.
#
# Copyright: 2009 Michigan State University Board of Trustees
########################################################################
library(MASS)
setwd("path_to_dir")
x <- read.table("data.txt", sep="\t", row.names=1, header=TRUE)
model_params_lower <- NULL
model_params_higher <- NULL
# There are 16 groups
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
nonlinear_modeling <- function(i){
subx <- subset(x, Grouping2 == i)
x.nls <- nls(measure ~ k * Min^a + c, data = subx, start = list(k = -0.65, a = 0.65, c = 80))
#################################################
#Diagnostic plots
#plot(subx$measure ~ predict(x.nls))
#x.m <- subx$measure - predict(x.nls)
#x.a <- sqrt(subx$measure * predict(x.nls))
#plot(x.m ~ x.a)
#################################################
x.conf <- confint(x.nls)
tx.conf <- t(x.conf)
v_params_lower <- c(i, tx.conf[1,])
v_params_higher <- c(i, tx.conf[2,])
model_params_lower <<- rbind(model_params_lower, v_params_lower)
model_params_higher <<- rbind(model_params_higher, v_params_higher)
return(TRUE)
}
February 23rd, 2010 - 08:49
This was really helpful, thank you! I just wasted a full hour going through the tryCatch and try documentation. I am not used to working with object classes. The one line of code
if(class(result) == “try-error”)
made all the difference!
June 8th, 2010 - 20:13
Thank you!
July 8th, 2010 - 13:24
thanks…it was a great help !
July 9th, 2010 - 18:31
To echo the other comments–hours spent in the try() documentation did not help, but this post was exactly what I needed.
Another way to address non-convergent nls is, supposedly, to use the ‘brute-force’ option in the package nls2, but I had bad luck with that too–probably because starting parameters were wildly out of range even of the gradient that I specified in nls2.
I would be curious to know whether you have tried nls2 instead of other methods like writing a selfStart function.
November 19th, 2010 - 22:53
Thank You very much! This information was very useful for my work!
But, dear collegues… In need to read manuals more carefully.
September 12th, 2011 - 23:46
Thank you! You just saved me hours of documentation reading and mistakes.
November 8th, 2011 - 08:25
Can I just say a big “Me too”? Extremely useful. I’ve been banging my head against exactly the same problem (parameter start values for nls). Thanks a lot!
February 8th, 2012 - 15:46
Super, thanks! I can finally have my lunch break now!
April 27th, 2012 - 16:23
Ditto. Thanks for the 411!
May 14th, 2012 - 15:08
brilliant!, thanks for the help
May 24th, 2012 - 12:01
Thanks a lot. I ended up just slipping the try() command around my nls() object and it is working beautifully.
July 5th, 2012 - 15:13
same problem.
Thanks for the solution.
November 14th, 2012 - 16:44
Again, nice explanation.