开发者

Why does R say no loop for break/next, jumping to top level

Why does R throw the error "Error in value[3L] : no loop for break/next, jumping to top level" instead of going to the next iteration of a loop? I'm on R version 2.13.1 (2011-07-08)

for (i in seq(10)) { 
   tryCatch(stop(), finally=print('whoops'), error=function(e) next) 
}

This problem came up because I wanted to create a different image or no image at all when plot failed. The code, using joran's approach, would look like this:

for (i in c(1,2,Inf)) { 
   fname = paste(sep='', 'f', i, '.png')
   png(fname, width=1024, height=768) 
   rs <- tryCatch(plot(i), error=function(e) NULL)
   if (is.null(rs)){
    print("I'll create a different picture because of the e开发者_如何学编程rror.")
   }
   else{
    print(paste('image', fname, 'created'))
    dev.off()
    next
   } 
}


Maybe you could try :

for (i in seq(10)) { 
   flag <- TRUE
   tryCatch(stop(), finally=print('whoops'), error=function(e) flag<<-FALSE)
   if (!flag) next
}


Unfortunately, once you get inside your error function you're no longer in a loop. There's a way you could hack around this:

for (i in seq(10)) { 
   delayedAssign("do.next", {next})
   tryCatch(stop(), finally=print('whoops'),
        error=function(e) force(do.next))
}

Though that is... well, hacky. Perhaps there is a less hacky way, but I don't see one right off.

(This works because delayedAssign happens every loop, canceling out the efforts of force)

EDIT

Or you could use continuations:

for (i in seq(10)) { 
   callCC(function(do.next) {
       tryCatch(stop(), finally=print('whoops'),
           error=function(e)    do.next(NULL))
       # Rest of loop goes here
       print("Rest of loop")
   })
}

EDIT

As Joris points out, you probably shouldn't actually use either of these, because they're confusing to read. But if you really want to call next in a loop, this is how :).


Wouldn't it make more sense to put the next outside the tryCatch based on an if check? Something like this:

for (i in c(1,2,Inf)) { 
   rs <- tryCatch(seq(i), finally=print('whoops'), error=function(e) NULL)
   if (is.null(rs)){
    print("I found an error!")
   }
   else{
    next
   } 
}

although I'm not sure this is what you want, since I'm a little unclear on what you're trying to do.

EDIT

Based on the OP's revisions, this formulation works for me:

plotFn <- function(fname,i){
    png(fname, width=400, height=200)
    plot(i)
    dev.off()
}


for (i in c(1,Inf,3)) { 
   fname = paste('f', i, '.png',sep="")
   rs <- tryCatch(plotFn(fname,i), error=function(e){dev.off(); return(NULL)})
   if (is.null(rs)){
    print("I'll create a different picture because of the error.")
   }
   else{
    print(paste('image', fname, 'created'))
    next
   } 
}

I'm certain that not having a dev.off() call in the case of an error needed to be fixed. I'd have to dig a little deeper to figure out exactly why separating png and plot was causing problems. But I think it's probably cleaner to keep the png(); plot(); dev.off() sequence self contained anyway. Also note that I put a dev.off() in the error function.

I haven't tested what will happen if plotFn throws an error on png(), never creates the device and then reaches the error function and calls dev.off(). Behavior may depend on what else you have going on in your R session.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜