为什么R抛出错误“错误值[3L]:没有循环中断/下一步,跳到顶层”而不是进入循环的下一次迭代?我在R版本2.13.1(2011-07-08)
for (i in seq(10)) {
tryCatch(stop(), finally=print('whoops'), error=function(e) next)
}
出现此问题是因为我想在绘图失败时创建不同的图像或根本没有图像。使用joran方法的代码看起来像这样:
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
}
}
答案 0 :(得分:8)
也许你可以试试:
for (i in seq(10)) {
flag <- TRUE
tryCatch(stop(), finally=print('whoops'), error=function(e) flag<<-FALSE)
if (!flag) next
}
答案 1 :(得分:4)
不幸的是,一旦你进入error
功能,你就不再处于循环中。有一种方法可以解决这个问题:
for (i in seq(10)) {
delayedAssign("do.next", {next})
tryCatch(stop(), finally=print('whoops'),
error=function(e) force(do.next))
}
虽然那是......好吧,哈基。也许有一种不那么黑客的方式,但我没有看到一个正确的。
(这可行,因为delayedAssign
每次循环都会发生,取消了force
的努力
修改
或者您可以使用延续:
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")
})
}
修改
正如Joris指出的那样,你可能不应该使用其中任何一种,因为它们令人困惑。但是如果你真的想在循环中调用next
,那么这就是:)。
答案 2 :(得分:2)
根据next
支票将tryCatch
放在if
之外会不会更有意义吗?像这样:
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
}
}
虽然我不确定这是你想要的,但我对你要做的事情有点不清楚。
修改强>
根据OP的修订版,这个配方适合我:
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
}
}
我确定在需要修复错误的情况下没有dev.off()
调用。我需要深入挖掘一下,找出确切地分离png
和plot
导致问题的原因。但我认为保持png(); plot(); dev.off()
序列自包含可能更加清晰。另请注意,我在错误函数中添加了dev.off()
。
我没有测试如果plotFn
在png()
上抛出错误会发生什么,从不创建设备然后到达错误函数并调用dev.off()
。行为可能取决于你在R会话中发生了什么。