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 error.")
}
else{
print(paste('image', fname, 'created'))
dev.off()
next
}
}
Wouldn't it make more sense to put the
next
outside thetryCatch
based on anif
check? Something like this: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:
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 separatingpng
andplot
was causing problems. But I think it's probably cleaner to keep thepng(); plot(); dev.off()
sequence self contained anyway. Also note that I put adev.off()
in the error function.I haven't tested what will happen if
plotFn
throws an error onpng()
, never creates the device and then reaches the error function and callsdev.off()
. Behavior may depend on what else you have going on in your R session.Maybe you could try :
Unfortunately, once you get inside your
error
function you're no longer in a loop. There's a way you could hack around this: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 offorce
)EDIT
Or you could use continuations:
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 :).