如何在R中写入trycatch

时间:2023-01-21 14:57:14

I want to write trycatch code to deal with error in downloading from 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:

这两个语句运行成功。下面,我创建一个不存在的web地址:

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

url[1] does not exist. How does one write a trycatch loop (function) so that:

url[1]不存在。如何编写一个trycatch循环(函数)以便:

  1. When the url is wrong, the output will be: "web url is wrong, can't get".
  2. 当url错误时,输出将是:“web url错误,无法获取”。
  3. When the url is wrong, the code does not stop, but continues to download until the end of list of urls?
  4. 当url错误时,代码不会停止,而是继续下载直到url列表结束?

4 个解决方案

#1


402  

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

tryCatch returns the value associated to executing expr unless there's an error or a warning. 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). These can be functions that already exist, but you can also define them within tryCatch() (as I did above).

tryCatch返回与执行expr相关的值,除非有错误或警告。在这种情况下,可以通过提供相应的处理程序函数来指定特定的返回值(请参阅?tryCatch中的参数错误和警告)。这些函数可以是已经存在的函数,但您也可以在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. 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. Also note that if you don't specify an explicit return value via return(), the handler functions will return NULL (i.e. in case of an error or a warning condition).

正如我们所指定的,在出错时应该返回NA, y中的第三个元素是NA。如果我们选择NULL作为返回值,y的长度应该是2而不是3,因为lapply()只会“忽略”NULL的返回值。还要注意,如果不通过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),如果您将它们用花括号括起来(就像我在最后部分中演示的那样)。

#2


47  

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’. The important thing to understand when writing each block of code is the state of execution and the scope. @source

在tryCatch()中有两个可以处理的“条件”:“警告”和“错误”。在编写每个代码块时需要理解的重要内容是执行的状态和范围。@source

#3


14  

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). FYI - irr is an actual function from FinCal in this case where got errors in a few cases on a large data set.

由于我刚刚浪费了两天时间试图解决irr函数的tryCatch,我认为我应该分享我的智慧(以及所缺少的)。FYI - irr是FinCal的一个实际的函数,在这个例子中,在一个大的数据集中出现了一些错误。

  1. Set up tryCatch as part of a function. For example:

    设置tryCatch作为函数的一部分。例如:

    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).

    记住创建一个子输出(比如我的“输出”)并返回(输出)。

#4


13  

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("My message is here!")
            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.

如果您还想捕获“警告”,只需添加与error= part类似的警告=。

#1


402  

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

tryCatch returns the value associated to executing expr unless there's an error or a warning. 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). These can be functions that already exist, but you can also define them within tryCatch() (as I did above).

tryCatch返回与执行expr相关的值,除非有错误或警告。在这种情况下,可以通过提供相应的处理程序函数来指定特定的返回值(请参阅?tryCatch中的参数错误和警告)。这些函数可以是已经存在的函数,但您也可以在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. 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. Also note that if you don't specify an explicit return value via return(), the handler functions will return NULL (i.e. in case of an error or a warning condition).

正如我们所指定的,在出错时应该返回NA, y中的第三个元素是NA。如果我们选择NULL作为返回值,y的长度应该是2而不是3,因为lapply()只会“忽略”NULL的返回值。还要注意,如果不通过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),如果您将它们用花括号括起来(就像我在最后部分中演示的那样)。

#2


47  

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’. The important thing to understand when writing each block of code is the state of execution and the scope. @source

在tryCatch()中有两个可以处理的“条件”:“警告”和“错误”。在编写每个代码块时需要理解的重要内容是执行的状态和范围。@source

#3


14  

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). FYI - irr is an actual function from FinCal in this case where got errors in a few cases on a large data set.

由于我刚刚浪费了两天时间试图解决irr函数的tryCatch,我认为我应该分享我的智慧(以及所缺少的)。FYI - irr是FinCal的一个实际的函数,在这个例子中,在一个大的数据集中出现了一些错误。

  1. Set up tryCatch as part of a function. For example:

    设置tryCatch作为函数的一部分。例如:

    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).

    记住创建一个子输出(比如我的“输出”)并返回(输出)。

#4


13  

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("My message is here!")
            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.

如果您还想捕获“警告”,只需添加与error= part类似的警告=。