我已经阅读了一些关于tryCatch
和cuzzins的其他SO问题,以及文档:
但我仍然不明白。
我正在运行循环,如果发生以下任何一种错误,我想跳到next
:
for (i in 1:39487) {
# EXCEPTION HANDLING
this.could.go.wrong <- tryCatch(
attemptsomething(),
error=function(e) next
)
so.could.this <- tryCatch(
doesthisfail(),
error=function(e) next
)
catch.all.errors <- function() { this.could.go.wrong; so.could.this; }
catch.all.errors;
#REAL WORK
useful(i); fun(i); good(i);
} #end for
(顺便说一下,我找不到next
的文档)
当我运行时,R
鸣喇叭:
Error in value[[3L]](cond) : no loop for break/next, jumping to top level
我在这里错过了什么基本观点? tryCatch
显然属于for
循环,为什么R
不知道呢?
答案 0 :(得分:73)
使用tryCatch
的关键是意识到它返回一个对象。如果tryCatch
内有错误,则此对象将继承自类error
。您可以使用函数inherit
来测试类继承。
x <- tryCatch(stop("Error"), error = function(e) e)
class(x)
"simpleError" "error" "condition"
修改:
参数error = function(e) e
的含义是什么?这让我感到困惑,我认为在文档中没有很好地解释它。会发生什么是该参数捕获源自您tryCatch
的表达式的任何错误消息。如果捕获到错误,则会返回tryCatch
的值。在帮助文档中,这被描述为calling handler
。 e
内的参数error=function(e)
是源自您代码的错误消息。
我来自程序式编程的旧学校,使用next
是一件坏事。所以我会像这样重写你的代码。 (请注意,我删除了next
中的tryCatch
语句。):
for (i in 1:39487) {
#ERROR HANDLING
possibleError <- tryCatch(
thing(),
error=function(e) e
)
if(!inherits(possibleError, "error")){
#REAL WORK
useful(i); fun(i); good(i);
}
} #end for
函数next
记录在?
for。。
如果您想使用它而不是在if
中使用主要工作例程,那么您的代码应如下所示:
for (i in 1:39487) {
#ERROR HANDLING
possibleError <- tryCatch(
thing(),
error=function(e) e
)
if(inherits(possibleError, "error")) next
#REAL WORK
useful(i); fun(i); good(i);
} #end for
答案 1 :(得分:5)
rm(list=ls())
for (i in -3:3) {
#ERROR HANDLING
possibleError <- tryCatch({
print(paste("Start Loop ", i ,sep=""))
if(i==0){
stop()
}
}
,
error=function(e) {
e
print(paste("Oops! --> Error in Loop ",i,sep = ""))
}
)
if(inherits(possibleError, "error")) next
print(paste(" End Loop ",i,sep = ""))
}
答案 2 :(得分:4)
我在这里可以找到唯一真正详细的解释:http://mazamascience.com/WorkingWithData/?p=912
以下是该博客帖子中的代码片段,其中显示了tryCatch的工作原理
#!/usr/bin/env Rscript
# tryCatch.r -- experiments with tryCatch
# Get any arguments
arguments <- commandArgs(trailingOnly=TRUE)
a <- arguments[1]
# Define a division function that can issue warnings and errors
myDivide <- function(d, a) {
if (a == 'warning') {
return_value <- 'myDivide warning result'
warning("myDivide warning message")
} else if (a == 'error') {
return_value <- 'myDivide error result'
stop("myDivide error message")
} else {
return_value = d / as.numeric(a)
}
return(return_value)
}
# Evalute the desired series of expressions inside of tryCatch
result <- tryCatch({
b <- 2
c <- b^2
d <- c+2
if (a == 'suppress-warnings') {
e <- suppressWarnings(myDivide(d,a))
} else {
e <- myDivide(d,a) # 6/a
}
f <- e + 100
}, warning = function(war) {
# warning handler picks up where error was generated
print(paste("MY_WARNING: ",war))
b <- "changing 'b' inside the warning handler has no effect"
e <- myDivide(d,0.1) # =60
f <- e + 100
return(f)
}, error = function(err) {
# warning handler picks up where error was generated
print(paste("MY_ERROR: ",err))
b <- "changing 'b' inside the error handler has no effect"
e <- myDivide(d,0.01) # =600
f <- e + 100
return(f)
}, finally = {
print(paste("a =",a))
print(paste("b =",b))
print(paste("c =",c))
print(paste("d =",d))
# NOTE: Finally is evaluated in the context of of the inital
# NOTE: tryCatch block and 'e' will not exist if a warning
# NOTE: or error occurred.
#print(paste("e =",e))
}) # END tryCatch
print(paste("result =",result))
答案 3 :(得分:3)
我遗漏的一件事breaking out of for loop when running a function inside a for loop in R明确指出:
next
在函数内部无效。Voldemort = TRUE
)向外部发送一些信号或标记(例如tryCatch
)。Voldemort == TRUE
)。如果是这样,请在函数外部调用break
或next
。答案 4 :(得分:1)
我发现其他答案非常令人困惑。对于任何想在发生错误时跳到下一个循环迭代的人来说,这都是一个非常简单的实现
for (i in 1:10) {
tryCatch(print(b), error = function(e) { print("hi"); skip_to_next <<- TRUE})
if(skip_to_next) { next }
}