在R 中错误时跳到循环的下一个值
我已经阅读了几个关于tryCatch
和cuzzins的SO问题以及文档:
- R中的exception处理
- 捕获一个错误,然后分支逻辑
- 如何检查函数调用是否导致警告?
- 循环中的情节问题
但我还是不明白。
我正在运行一个循环,并且如果发生几种错误中的任何一种,就想跳到next
一个循环:
for (i in 1:39487) { #ERROR 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
我没有find任何文档)
当我运行这个, R
hon:
Error in value[[3L]](cond) : no loop for break/next, jumping to top level
我在这里想念什么基本点? tryCatch
显然在for
循环中,为什么R
不知道呢?
使用tryCatch
的关键是实现它返回一个对象。 如果tryCatch
内部有错误,则此对象将从类error
inheritance。 您可以使用函数inherit
来testing类inherit
。
x <- tryCatch(stop("Error"), error = function(e) e) class(x) "simpleError" "error" "condition"
编辑:
参数error = function(e) e
是什么意思? 这使我感到困惑,我不认为这是在文档中很好解释。 会发生什么呢是这个参数捕获来自您tryCatch
ingexpression式的任何错误消息。 如果发现一个错误,它将作为tryCatch
的值返回。 在帮助文档中,这被描述为calling handler
。 在error=function(e)
里面的参数e
是源于你的代码的错误信息。
我来自程序编程的老派,使用next
是一件坏事。 所以我会重写你的代码是这样的。 (请注意,我删除了tryCatch
的next
语句。):
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
下面的函数是在里面logging的?
for`。
如果你想使用它,而不是在你的主要工作例程,你的代码应该是这样的:
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
我见过的唯一真正详细的解释可以在这里find: 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))
有一件事,我错过了, 当在R中的for循环中运行一个函数时 , 打破for循环清楚,是这样的:
-
next
在一个函数里面不起作用。 - 你需要从你的函数(在我的情况
tryCatch
)发送一些信号或标志(例如,Voldemort = TRUE
)到外面。 - (这就像修改本地私有函数中的全局公共variables)
- 然后在函数外面,检查标志是否挥手(
Voldemort == TRUE
)。 如果是这样,你可以在函数外面调用break
或next
。
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 = "")) }