如何在R中编写trycatch

本文翻译自:How to write trycatch in R

I want to write trycatch code to deal with error in downloading from the web. 我想编写trycatch代码来处理从Web下载时的错误。

url <- c(
    "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
    "http://en.wikipedia.org/wiki/Xz")
y <- mapply(readLines, con=url)

These two statements run successfully. 这两个语句成功运行。 Below, I create a non-exist web address: 在下面,我创建了一个不存在的网址:

url <- c("xxxxx", "http://en.wikipedia.org/wiki/Xz")

url[1] does not exist. url[1]不存在。 How does one write a trycatch loop (function) so that: 一个人如何编写一个trycatch循环(函数),以便:

  1. When the URL is wrong, the output will be: "web URL is wrong, can't get". 如果URL错误,输出将为:“ Web URL错误,无法获取”。
  2. When the URL is wrong, the code does not stop, but continues to download until the end of the list of URLs? 如果URL错误,代码不会停止,而是继续下载直到URL列表的末尾?

#1楼

参考:https://stackoom.com/question/pA9r/如何在R中编写trycatch


#2楼

R uses functions for implementing try-catch block: R使用函数来实现try-catch块:

The syntax somewhat looks like this: 语法看起来像这样:

result = tryCatch({
    expr
}, warning = function(warning_condition) {
    warning-handler-code
}, error = function(error_condition) {
    error-handler-code
}, finally={
    cleanup-code
})

In tryCatch() there are two 'conditions' that can be handled: 'warnings' and 'errors'. 在tryCatch()中,可以处理两个“条件”:“警告”和“错误”。 The important thing to understand when writing each block of code is the state of execution and the scope. 编写每个代码块时要了解的重要事项是执行状态和范围。 @source @资源


#3楼

Well then: welcome to the R world ;-) 好吧:欢迎来到R世界;-)

Here you go 干得好

Setting up the code 设置代码

urls <- c(
    "http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html",
    "http://en.wikipedia.org/wiki/Xz",
    "xxxxx"
)
readUrl <- function(url) {
    out <- tryCatch(
        {
            # Just to highlight: if you want to use more than one 
            # R expression in the "try" part then you'll have to 
            # use curly brackets.
            # 'tryCatch()' will return the last evaluated expression 
            # in case the "try" part was completed successfully

            message("This is the 'try' part")

            readLines(con=url, warn=FALSE) 
            # The return value of `readLines()` is the actual value 
            # that will be returned in case there is no condition 
            # (e.g. warning or error). 
            # You don't need to state the return value via `return()` as code 
            # in the "try" part is not wrapped insided a function (unlike that
            # for the condition handlers for warnings and error below)
        },
        error=function(cond) {
            message(paste("URL does not seem to exist:", url))
            message("Here's the original error message:")
            message(cond)
            # Choose a return value in case of error
            return(NA)
        },
        warning=function(cond) {
            message(paste("URL caused a warning:", url))
            message("Here's the original warning message:")
            message(cond)
            # Choose a return value in case of warning
            return(NULL)
        },
        finally={
        # NOTE:
        # Here goes everything that should be executed at the end,
        # regardless of success or error.
        # If you want more than one expression to be executed, then you 
        # need to wrap them in curly brackets ({...}); otherwise you could
        # just have written 'finally=<expression>' 
            message(paste("Processed URL:", url))
            message("Some other message at the end")
        }
    )    
    return(out)
}

Applying the code 应用代码

> y <- lapply(urls, readUrl)
Processed URL: http://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html
Some other message at the end
Processed URL: http://en.wikipedia.org/wiki/Xz
Some other message at the end
URL does not seem to exist: xxxxx
Here's the original error message:
cannot open the connection
Processed URL: xxxxx
Some other message at the end
Warning message:
In file(con, "r") : cannot open file 'xxxxx': No such file or directory

Investigating the output 调查输出

> head(y[[1]])
[1] "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"      
[2] "<html><head><title>R: Functions to Manipulate Connections</title>"      
[3] "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
[4] "<link rel=\"stylesheet\" type=\"text/css\" href=\"R.css\">"             
[5] "</head><body>"                                                          
[6] ""    

> length(y)
[1] 3

> y[[3]]
[1] NA

Additional remarks 补充说明

tryCatch 试着抓

tryCatch returns the value associated to executing expr unless there's an error or a warning. 除非有错误或警告,否则tryCatch返回与执行expr相关的值。 In this case, specific return values (see return(NA) above) can be specified by supplying a respective handler function (see arguments error and warning in ?tryCatch ). 在这种情况下,可以通过提供相应的处理函数来指定特定的返回值(请参见上面的return(NA) )(请参见?tryCatch参数errorwarning )。 These can be functions that already exist, but you can also define them within tryCatch() (as I did above). 这些可以是已经存在的函数,但是您也可以在tryCatch()定义它们(就像我上面所做的那样)。

The implications of choosing specific return values of the handler functions 选择处理程序函数的特定返回值的含义

As we've specified that NA should be returned in case of error, the third element in y is NA . 正如我们指定NA应该在出错的情况下返回,在第三个元素yNA If we'd have chosen NULL to be the return value, the length of y would just have been 2 instead of 3 as lapply() will simply "ignore" return values that are NULL . 如果我们选择NULL作为返回值,则y的长度应该是2而不是3因为lapply()会简单地“忽略”返回值NULL Also note that if you don't specify an explicit return value via return() , the handler functions will return NULL (ie in case of an error or a warning condition). 还要注意,如果未通过return()指定显式的返回值,则处理函数将返回NULL (即,在发生错误或警告条件的情况下)。

"Undesired" warning message “不希望的”警告消息

As warn=FALSE doesn't seem to have any effect, an alternative way to suppress the warning (which in this case isn't really of interest) is to use 由于warn=FALSE似乎没有任何效果,因此可以使用一种替代方法来抑制警告(在这种情况下,这种警告并不重要)

suppressWarnings(readLines(con=url))

instead of 代替

readLines(con=url, warn=FALSE)

Multiple expressions 多种表达

Note that you can also place multiple expressions in the "actual expressions part" (argument expr of tryCatch() ) if you wrap them in curly brackets (just like I illustrated in the finally part). 请注意,如果您将多个表达式用大括号括起来,也可以将它们放置在“实际表达式部分”( tryCatch()参数expr )中(就像我在finally一部分中说明的那样)。


#4楼

Since I just lost two days of my life trying to solve for tryCatch for an irr function, I thought I should share my wisdom (and what is missing). 由于我一生只花了两天时间试图为一个irr函数解决tryCatch问题,所以我认为我应该分享自己的智慧(以及所缺少的)。 FYI - irr is an actual function from FinCal in this case where got errors in a few cases on a large data set. FYI-在这种情况下,irr是FinCal的一项实际功能,在少数情况下,大型数据集会出现错误。

  1. Set up tryCatch as part of a function. 将tryCatch设置为函数的一部分。 For example: 例如:

     irr2 <- function (x) { out <- tryCatch(irr(x), error = function(e) NULL) return(out) } 
  2. For the error (or warning) to work, you actually need to create a function. 为了使错误(或警告)生效,您实际上需要创建一个函数。 I originally for error part just wrote error = return(NULL) and ALL values came back null. 我最初对于错误部分只写了error = return(NULL)并且所有值都返回null。

  3. Remember to create a sub-output (like my "out") and to return(out) . 记住要创建一个子输出(例如我的“ out”)并return(out)


#5楼

Here goes a straightforward example : 这是一个简单的例子

# Do something, or tell me why it failed
my_update_function <- function(x){
    tryCatch(
        # This is what I want to do...
        {
        y = x * 2
        return(y)
        },
        # ... but if an error occurs, tell me what happened: 
        error=function(error_message) {
            message("This is my custom message.")
            message("And below is the error message from R:")
            message(error_message)
            return(NA)
        }
    )
}

If you also want to capture a "warning", just add warning= similar to the error= part. 如果您还想捕获“警告”,只需添加warning=类似于error=部分。


#6楼

tryCatch has a slightly complex syntax structure. tryCatch具有稍微复杂的语法结构。 However, once we understand the 4 parts which constitute a complete tryCatch call as shown below, it becomes easy to remember: 但是,一旦我们理解了构成一个完整的tryCatch调用的4个部分,如下所示,就很容易记住:

expr : [ Required ] R code(s) to be evaluated expr :[ 必需 ]要评估的R代码

error : [ Optional ] What should run if an error occured while evaluating the codes in expr 错误 :[ 可选 ]如果在评估expr中的代码时发生错误,应该怎么办

warning : [ Optional ] What should run if a warning occured while evaluating the codes in expr 警告 :[ 可选 ]如果在评估expr中的代码时发生警告,应该怎么办

finally : [ Optional ] What should run just before quitting the tryCatch call, irrespective of if expr ran successfully, with an error, or with a warning 最终 :[ 可选 ]退出tryCatch调用之前应该执行什么操作,而不管expr是否成功运行,是否有错误或警告

tryCatch(
    expr = {
        # Your code...
        # goes here...
        # ...
    },
    error = function(e){ 
        # (Optional)
        # Do this if an error is caught...
    },
    warning = function(w){
        # (Optional)
        # Do this if an warning is caught...
    },
    finally = {
        # (Optional)
        # Do this at the end before quitting the tryCatch structure...
    }
)

Thus, a toy example, to calculate the log of a value might look like: 因此,一个用于计算值对数的玩具示例可能类似于:

log_calculator <- function(x){
    tryCatch(
        expr = {
            message(log(x))
            message("Successfully executed the log(x) call.")
        },
        error = function(e){
            message('Caught an error!')
            print(e)
        },
        warning = function(w){
            message('Caught an warning!')
            print(w)
        },
        finally = {
            message('All done, quitting.')
        }
    )    
}

Now, running three cases: 现在,运行三种情况:

A valid case 有效案例

log_calculator(10)
# 2.30258509299405
# Successfully executed the log(x) call.
# All done, quitting.

A "warning" case “警告”案

log_calculator(-10)
# Caught an warning!
# <simpleWarning in log(x): NaNs produced>
# All done, quitting.

An "error" case “错误”案例

log_calculator("log_me")
# Caught an error!
# <simpleError in log(x): non-numeric argument to mathematical function>
# All done, quitting.

I've written about some useful use-cases which I use regularly. 我写了一些我经常使用的有用用例。 Find more details here: https://rsangole.netlify.com/post/try-catch/ 在此处查找更多详细信息: https : //rsangole.netlify.com/post/try-catch/

Hope this is helpful. 希望这会有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值