错误时是否使用tryCatch跳过循环的下一个值?
我已经阅读了一些关于错误时是否使用tryCatch跳过循环的下一个值?,r,error-handling,exception-handling,try-catch,R,Error Handling,Exception Handling,Try Catch,我已经阅读了一些关于tryCatch和cuzzins的其他SO问题,以及文档: 但我还是不明白 我正在运行一个循环,如果出现以下几种错误中的任何一种,我想跳到下一步: for (i in 1:39487) { # EXCEPTION HANDLING this.could.go.wrong <- tryCatch( attemptsomething(), err
tryCatch
和cuzzins的其他SO问题,以及文档:
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
我在这里遗漏了什么基本点?
tryCatch
显然在for
循环中,那么为什么R
不知道这一点呢?使用tryCatch
的关键是意识到它返回一个对象。如果tryCatch
中存在错误,则此对象将从类error
继承。您可以使用函数inherit
测试类继承
x <- tryCatch(stop("Error"), error = function(e) e)
class(x)
"simpleError" "error" "condition"
函数
next
记录在`的?
中
如果您想使用它,而不是将主工作例程放在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
for(i在1:39487中){
#错误处理
可能的错误我遗漏了一件事,很清楚,那就是:
next
在函数内部不起作用
- 您需要从函数内部(在我的例子中是
tryCatch
)向外部发送一些信号或标志(例如,Voldemort=TRUE
)
- (这类似于在局部私有函数中修改全局公共变量)
- 然后在函数外部,检查是否挥动了旗帜(伏地魔==TRUE
)。如果是这样,则在函数外部调用break
或next
- 我所看到的唯一真正详细的解释可以在这里找到:
下面是那篇博客文章的代码片段,展示了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))
!/usr/bin/env Rscript
#tryCatch.r——使用tryCatch的实验
#有什么论据吗
(i in-3:3)的参数{
#错误处理
可能错误我发现其他答案非常令人困惑。这里是一个非常简单的实现,适用于任何想在发生错误时直接跳到下一个循环迭代的人
for (i in 1:10) {
skip_to_next <- FALSE
# Note that print(b) fails since b doesn't exist
tryCatch(print(b), error = function(e) { skip_to_next <<- TRUE})
if(skip_to_next) { next }
}
for(1:10中的i){
跳到下一个谢谢你的回答。我本来是像你建议的那样避免下一个的,但是当我想到越来越多可能被发现的错误时,代码变成了一堆括号:和“编程”一样糟糕或者更糟糕Excel单元格中的一系列条件。当我运行?对于,下一行是+
(请求更多输入)@Andrie,如果函数为空,写error=function(e)
有什么意义?这应该是其他东西的缩写吗?我的错误。应该是error=function(e)e
。这将返回错误消息。我还在回答中添加了对该机制的解释。我很好奇,为什么您更喜欢避免“下一步”——无论是旧学校还是新学校,这通常被认为是良好的实践输入法。与“下一步被认为是有害的”非常不同事实上,这是非常有害的。但是循环控制操作符可以极大地简化代码并消除前哨变量,因为前哨变量往往有令人讨厌的边缘情况。正如@laotzi所指出的,你可以节省大量的括号和大括号。事实上,这是可能的,不是一种优雅的方式,但仍然是:最后!这么多复杂的解释。但在这里,你可以简化了整个过程,为社区做出了巨大的贡献。对于那些对
#!/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))
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 = ""))
}
for (i in 1:10) {
skip_to_next <- FALSE
# Note that print(b) fails since b doesn't exist
tryCatch(print(b), error = function(e) { skip_to_next <<- TRUE})
if(skip_to_next) { next }
}