[R] avoid error within for loop, try, trycatch, while, move to next iteration, unlist

William Dunlap wdunlap at tibco.com
Sat May 26 19:10:41 CEST 2012


You could encapsulate this idiom in a function:

untilOK <- function (expr, silent = TRUE, maxIter = 1000,
    quotedExpr = substitute(expr),  envir = parent.frame()) 
{
    while ((maxIter <- maxIter - 1) >= 0 && inherits(tmp <- try(eval(quotedExpr, 
        envir = envir), silent = silent), "try-error")) {
    }
    if (maxIter < 0) {
        stop("reached maxIter iterations, last error message is ", 
            as.character(tmp))
    }
    tmp
}

E.g.,

  > f <- function(x){ stopifnot(x>0.9) ; x } # fails 90% of time
  > vapply(1:10, function(i)untilOK(f(runif(1))), FUN.VALUE=0.0)
   [1] 0.9460461 0.9670447 0.9306208 0.9122009 0.9495725 0.9619204 0.9031418 0.9624259 0.9809273 0.9518705
  > untilOK(stopifnot(1==2)) # maxIter=1000 protects against inappropriate expressions.
  Error in untilOK(stopifnot(1 == 2)) : 
    reached maxIter iterations, last error message is Error : 1 == 2 is not TRUE

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of William Dunlap
> Sent: Saturday, May 26, 2012 9:20 AM
> To: Λεωνίδας Μπαντής; r-help at r-project.org
> Subject: Re: [R] avoid error within for loop, try, trycatch, while, move to next iteration,
> unlist
> 
> You could put the try() into a while loop, inside for for or lapply loop,
> as in:
> 
> > f <- function(x){ stopifnot(x>0.5) ; x }
> > o <- numeric(100); for(i in seq_along(o)) { while(inherits(try(tmp <- f(runif(1)),
> silent=TRUE), "try-error")) {} ; o[[i]] <- tmp }
> > range(o)
> [1] 0.5000588 0.9991261
> 
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com
> 
> 
> > -----Original Message-----
> > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> > Of ?e???da? ?pa?t??
> > Sent: Saturday, May 26, 2012 6:15 AM
> > To: r-help at r-project.org
> > Subject: [R] avoid error within for loop, try, trycatch, while, move to next iteration,
> unlist
> >
> >
> >
> >
> > Hi there,
> >
> > I would like to ask something about how to avoid a possible error message within a for
> > loop. I am running a simulation and in some repetitions there may be an error that will
> > cause a crash and stop the whole procedure, what I want is to simply move on to the
> > next iteration automatically and discard the "bad" repetitions from my results. I used
> the
> > "try" function to do this and it partially works.
> >
> > Here is the thing:
> >
> > logitsboots <- function(x,y,Jbh) {
> > logitseb=0;logitspb=0;
> > for (j in 1:1) {
> >
> >
> > #some code here that has to do with random numbers that may or may not produce an
> > error and calculates the values of two scalar quantities: spboots  and seboots,
> >
> >
> >   logitspb=log(spboots/(1-spboots))
> >   logitseb=log(seboots/(1-seboots))
> >
> > #assume that I only care about logitseb for the moment
> > }
> > list(lse=logitseb)
> >
> > }
> >
> >
> >
> > # Now the following works just fine:
> >
> >
> > res=0
> > for(bb in 1:100) {
> > res[bb] <- try(logitsboots(x,y,Jbh), TRUE)
> >     }
> > az=unlist(res[sapply(res, function(x) !inherits(x, "try-error"))])
> >
> >
> >
> >
> > #So far, so good and everything is working fine with "az" having the values of lse having
> > also discarded the "bad" iterations.
> >
> >
> > However I would like to store (as an output) both values (logitse AND logitsp) in the
> > function logitsboots, that is the list would be as :
> >
> >
> > list(lse=logitseb,lsp=logitspb).
> >
> > This way the quantity "res" would have two arguments: res$lse and res$lsp each time it
> is
> > called. However when an error occures I just cannot seem to manage to "unlist" the
> "res"
> > properly since typing "res$lse" for example will warn me that the "$" operator will not
> > work (since it is not numeric anymore I guess). Something like the following would fail,
> > but I guess that clears what I want to do.
> >
> >
> > az1=unlist(res$lse[sapply(res$lse, function(x) !inherits(x, "try-error"))])
> >
> > az2=unlist(res$lsp[sapply(res$lsp, function(x) !inherits(x, "try-error"))])
> >
> > My final goal is to obtain 100 values of lse and 100 values of lsp. (Of course since the
> > iterations leading to an error would be discarded I will end up with less than 100
> > iterations. Any ideas of also using the "while" here in combination with the "try" to just
> > discard the bad iterations and replace them with new good ones would be great. This
> > way I would actually get exactly 100 values of lse and lsp).
> >
> > Most important is to manage to keep both values in a two column matrix or something.
> I
> > hope I was clear enough..
> >
> >
> >
> > Thanx in advance for any answers!
> >
> > Leo.
> > 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list