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

Posted

技术标签:

【中文标题】如何告诉 lapply 忽略错误并处理列表中的下一件事?【英文标题】:How to tell lapply to ignore an error and process the next thing in the list? 【发布时间】:2011-02-05 01:35:10 【问题描述】:

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

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”字符串的错误?

【问题讨论】:

密切相关:***.com/questions/1395622/… 【参考方案1】:

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

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

tryCatch 函数的好处在于,您可以决定在出现错误时该怎么做(在这种情况下,返回 NULL)。

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

[[2]]
NULL

[[3]]
[1] "2010-04-08"

【讨论】:

归根结底,我们都在这里做同样的事情——John 不需要异常处理。如果不是日期,则返回 NA。为什么要让事情变得更加困难? 是的,在这种情况下确实如此。尽管如果问题被概括,那么使用tryCatch 可能是继续解决lapply 中的错误的最佳方法。我认为日期示例只是一个示例? 感谢 Dirk 和 Shane,实际上我正在寻找异常处理。日期只是一个更复杂函数的示例,但这是我能想到的最简单的方法,它会从事物列表中返回错误。 另请参阅 plyr 中的 failwith 函数,该函数可自动执行此常见任务。 另一种可能性是在 lapply 中添加 tryCatch 并让函数引发错误。照常。 lapply(dates2, function(x) tryCatch(testFunctionWihoutTryCatch(x), error=function(e) NULL))。当然,在这种特殊情况下,Dirk 的评论非常有意义。【参考方案2】:

人们可以尽量保持简单而不是让它变得复杂:

使用矢量化日期解析
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 类型中,否则您无法轻松混合类型。所以也许你需要重新考虑一下。

【讨论】:

【参考方案3】:

假设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"

【讨论】:

【参考方案4】:

您也可以使用purrr 辅助函数mappossibly 完成此类任务。比如

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

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

【讨论】:

以上是关于如何告诉 lapply 忽略错误并处理列表中的下一件事?的主要内容,如果未能解决你的问题,请参考以下文章

如何等待http请求在处理到angular 7中的下一步之前获得响应[重复]

忽略 jdbc 批处理中的错误语句

如何访问本网站的下一页?

获取循环中的下一项

处理嵌套列表

如何使用lapply来计算r中列表中的唯一值