R中的异常处理


97

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


1
这也是一个很好的例子:stackoverflow.com/q/12193779/2026975
13年

我发现此博客文章非常有用:http
//mazamascience.com/WorkingWithData/?p=912

Answers:


31

除了Shane的答案可以将您引向其他StackOverflow讨论之外,您还可以尝试使用代码搜索功能。此原始答案指向Google的代码搜索,此后已停止使用,但您可以尝试

只是为了记录在案,也有try,但tryCatch可能是可取的。我在Google代码搜索中尝试了一下快速计数,但是尝试对动词本身获取了太多的误报-但它似乎tryCatch得到了更广泛的使用。


也许这个例子可以帮助您:http
//stackoverflow.com/a/12195574/2026975

一个Github上搜索可能的倒闭链接一个体面的替代品。
Gregor Thomas

所有链接都断开了。
Toros91 '18

60

基本上,您想使用该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")) 

看一下这些相关的问题:



8

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

可以说一个低级的程序员编写了一个函数来计算绝对值。他不确定如何计算,但知道如何构造错误并努力传达自己的天真:

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_value 当的值为x负时,低级代码将引发错误,并通过建立允许用户控制错误恢复(或不恢复)的方式来建议解决问题的方法。restartmid_level_ABSmid_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_ABSnegative_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()and 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)。


7

在从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(){})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.