在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内部有错误,则此对象将从类errorinheritance。 您可以使用函数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是一件坏事。 所以我会重写你的代码是这样的。 (请注意,我删除了tryCatchnext语句。):

 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 )。 如果是这样,你可以在函数外面调用breaknext
 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 = "")) }