如何告诉lapply忽略错误并处理列表中的下一个事情?

Joh*_*n 35 error-handling r try-catch lapply

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

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

testFunction("2010-04-06")  # this works fine
testFunction("foo")  # this returns an error
Run Code Online (Sandbox Code Playgroud)

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

dates1 = c("2010-04-06", "2010-04-07", "2010-04-08")
lapply(dates1, testFunction)  # this works fine
Run Code Online (Sandbox Code Playgroud)

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

dates2 = c("2010-04-06", "foo", "2010-04-08")
lapply(dates2, testFunction)
Run Code Online (Sandbox Code Playgroud)

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

Sha*_*ane 59

使用tryCatch可以抛出错误消息的函数周围的表达式:

testFunction <- function (date_in) {
  return(tryCatch(as.Date(date_in), error=function(e) NULL))
}
Run Code Online (Sandbox Code Playgroud)

关于该tryCatch函数的好处是你可以决定在出错的情况下该做什么(在这种情况下,返回NULL).

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

[[2]]
NULL

[[3]]
[1] "2010-04-08"
Run Code Online (Sandbox Code Playgroud)

  • 另请参阅`plyr`中的`failwith`函数,它可以自动执行此常见任务. (3认同)

Dir*_*tel 7

人们可以尝试保持简单,而不是让它变得复杂:

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

你可以简单地包裹na.omit()它或周围的任何东西.或者找到NA的索引并从初始向量中相应地提取,或者使用NA的补充来查找已解析的日期,或者,或,或.它已经在这里了.

  • 你可以让你testFunction()做点什么.在那里使用测试 - 如果返回(解析)日期是NA,则执行某些操作.

  • 添加tryCatch()块或a try()到您的日期解析.

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


MrF*_*ick 7

purrr您还可以使用辅助函数map和来完成此类任务possibly。例如

library(purrr)
map(dates2, possibly(testFunction, NA))
Run Code Online (Sandbox Code Playgroud)

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