【问题标题】:Exception handling in R [closed]R中的异常处理[关闭]
【发布时间】:2011-02-07 01:02:51
【问题描述】:

有人有 R 中异常处理的示例/教程吗?官方文档非常简洁。

【问题讨论】:

标签: r exception-handling


【解决方案1】:

函数trycatch() 相当简单,并且有很多很好的教程。可以在 Hadley Wickham 的书 Advanced-R 中找到对 R 中错误处理的出色解释,以下是对 withCallingHandlers()withRestarts()非常基本介绍,用尽可能少的文字介绍:

假设一个低级程序员编写了一个函数来计算绝对值 价值。他不确定如何计算,但知道how to construct an error 和 努力表达他的天真:

low_level_ABS <- function(x){
    if(x<0){
        #construct an error
        negative_value_error <- structure(
                    # with class `negative_value`
                    class = c("negative_value","error", "condition"),
                    list(message = "Not Sure what to with a negative value",
                         call = sys.call(), 
                         # and include the offending parameter in the error object
                         x=x))
        # raise the error
        stop(negative_value_error)
    }
    cat("Returning from low_level_ABS()\n")
    return(x)
}

中级程序员还编写了一个函数来计算绝对值,利用可悲的不完整的low_level_ABS 函数。他知道低级代码抛出一个negative_valuex 的值为负并且建议解决问题时出错,通过 建立一个restart 允许mid_level_ABS 的用户控制 mid_level_ABSnegative_value 错误中恢复(或不恢复)的方式。

mid_level_ABS <- function(y){
    abs_y <- withRestarts(low_level_ABS(y), 
                          # establish a restart called 'negative_value'
                          # which returns the negative of it's argument
                          negative_value_restart=function(z){-z}) 
    cat("Returning from mid_level_ABS()\n")
    return(abs_y)
}

最后,高级程序员使用mid_level_ABS 函数来计算 绝对值,并建立一个条件处理程序,告诉 mid_level_ABS 通过使用重新启动从 negative_value 错误中恢复 处理程序。

high_level_ABS <- function(z){
    abs_z <- withCallingHandlers(
            # call this function
            mid_level_ABS(z) ,
            # and if an `error` occurres
            error = function(err){
                # and the `error` is a `negative_value` error
                if(inherits(err,"negative_value")){
                    # invoke the restart called 'negative_value_restart'
                    invokeRestart('negative_value_restart', 
                                     # and invoke it with this parameter
                                     err$x) 
                }else{
                    # otherwise re-raise the error
                    stop(err)
                }
            })
    cat("Returning from high_level_ABS()\n")
    return(abs_z)
}

所有这一切的重点是通过使用withRestarts()withCallingHandlers(),函数 high_level_ABS 能够告诉 mid_level_ABS 如何从错误中恢复 由low_level_ABS 引发的错误而没有停止执行 mid_level_ABS,这是tryCatch()做不到的:

> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3

实际上,low_level_ABS 表示mid_level_ABS 调用的函数 很多(甚至可能是数百万次),其中正确的错误方法 处理可能因情况而异,如何处理特定错误的选择是 留给更高级别的功能 (high_level_ABS)。

【讨论】:

    【解决方案2】:

    除了 Shane 将您指向其他 StackOverflow 讨论的回答之外,您还可以尝试使用代码搜索功能。这个指向谷歌代码搜索的原始答案已经停止,但你可以尝试

    仅作记录,还有try,但tryCatch 可能更可取。我尝试在 Google 代码搜索中快速计数,但尝试对动词本身产生太多误报 - 但似乎 tryCatch 使用更广泛。

    【讨论】:

    【解决方案3】:

    Restart 函数在继承自 Lisp 的 R 中非常重要。如果您想在循环体中调用某个函数并且只想在函数调用崩溃时让程序继续运行,这很有用。试试这个代码:

    for (i in 1:20) withRestarts(tryCatch(
    if((a <- runif(1))>0.5) print(a) else stop(a),
    finally = print("loop body finished!")), 
    abort = function(){})
    

    【讨论】:

      【解决方案4】:

      这个来自相关谷歌搜索的结果帮助了我:http://biocodenv.com/wordpress/?p=15

      for(i in 1:16){
      result <- try(nonlinear_modeling(i));
      if(class(result) == "try-error") next;
      }
      

      【讨论】:

        【解决方案5】:

        基本上你想使用tryCatch() 函数。查看 help("tryCatch") 了解更多详情。

        这是一个简单的例子(请记住,你可以做任何你想做的错误):

        vari <- 1
        tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished")) 
        tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished")) 
        

        看看这些相关的问题:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-29
          • 1970-01-01
          • 1970-01-01
          • 2011-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多