Biocodenv Blog Bioinformatics, Code, Stuff

3Sep/0915

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)
}

Comments (15) Trackbacks (0)
  1. 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!

  2. Thank you!

  3. thanks…it was a great help !

  4. 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.

  5. Thank You very much! This information was very useful for my work!

    But, dear collegues… In need to read manuals more carefully. :(

  6. Thank you! You just saved me hours of documentation reading and mistakes.

  7. 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!

  8. Super, thanks! I can finally have my lunch break now!

  9. Ditto. Thanks for the 411!

  10. brilliant!, thanks for the help

  11. Thanks a lot. I ended up just slipping the try() command around my nls() object and it is working beautifully.

  12. same problem.
    Thanks for the solution.

  13. Again, nice explanation.

  14. This was really really helpful… I’ve been struggling for days with wow to do this for a similar gnls code.

  15. Thanks for this post!


Leave a comment

No trackbacks yet.