43

我在下面有一个示例函数,它将日期作为字符串读取并将其作为日期对象返回。如果它读取一个无法转换为日期的字符串,它会返回一个错误。

testFunction <- function (date_in) {
    return(as.Date(date_in))
    }

testFunction("2010-04-06")  # this works fine
testFunction("foo")  # this returns an error

现在,我想使用 lapply 并将此函数应用于日期列表:

dates1 = c("2010-04-06", "2010-04-07", "2010-04-08")
lapply(dates1, testFunction)  # this works fine

但是,如果我想在两个好日期中间的一个字符串返回错误时将函数应用于列表,那么处理这个问题的最佳方法是什么?

dates2 = c("2010-04-06", "foo", "2010-04-08")
lapply(dates2, testFunction)

我想我想在那里尝试捕获,但是有没有办法在要求 lapply 继续并阅读第三个日期的同时捕获“foo”字符串的错误?

4

4 回答 4

70

tryCatch在可能引发错误消息的函数周围使用表达式:

testFunction <- function (date_in) {
  return(tryCatch(as.Date(date_in), error=function(e) NULL))
}

tryCatch函数的好处是您可以决定在发生错误时要做什么(在本例中为 return NULL)。

> lapply(dates2, testFunction)
[[1]]
[1] "2010-04-06"

[[2]]
NULL

[[3]]
[1] "2010-04-08"
于 2010-04-07T01:01:01.800 回答
8

可以尝试保持简单而不是使其复杂:

  • 使用矢量化日期解析
R> as.Date( c("2010-04-06", "foo", "2010-04-08") )
[1] "2010-04-06" NA           "2010-04-08"

您可以简单地包裹na.omit()或围绕它。或者找到NAs的索引并从初始向量中相应地提取,或者使用NAs的补码来找到解析的日期,or,or,or。一切都已经在这里了。

  • 你可以让你testFunction()做点什么。在那里使用测试——如果返回(解析)的日期是 NA,做点什么。

  • 在您的日期解析中添加一个tryCatch()块或一个。try()

当您从一种类型的数据结构(字符向量)转到其他类型时,整个事情有点奇怪,但是除非您将它们保存在一个类型中,否则您不能轻松地混合类型list。所以也许你需要重新考虑这一点。

于 2010-04-07T01:01:13.283 回答
4

您还可以使用purrr辅助函数mappossibly. 例如

library(purrr)
map(dates2, possibly(testFunction, NA))

这里possibly将返回 NA (或者如果发生错误,您指定的任何值。

于 2020-07-31T01:18:25.177 回答
0

假设testFunction()它不是微不足道的和/或无法改变它,它可以包装在你自己的函数中,带有一个 tryCatch() 块。例如:

> FaultTolerantTestFunction <- function(date_in) {
+    tryCatch({ret <- testFunction(date_in);}, error = function(e) {ret <<- NA});
+    ret
+ }
> FaultTolerantTestFunction('bozo')
[1] NA
> FaultTolerantTestFunction('2010-03-21')
[1] "2010-03-21"
于 2010-04-07T01:03:17.183 回答