如何将警告和错误保存为函数的输出? [英] How do I save warnings and errors as output from a function?
问题描述
我正在使用 lapply
在大量项目上运行复杂的函数,并且我想保存每个项目的输出(如果有)以及任何警告/错误生成以便我可以判断哪个项目生成了哪个警告/错误.
I'm using lapply
to run a complex function on a large number of items, and I'd like to save the output from each item (if any) together with any warnings/errors that were produced so that I can tell which item produced which warning/error.
我找到了一种使用 withCallingHandlers
(此处描述)来捕捉警告的方法.但是,我也需要捕捉错误.我可以通过将它包装在 tryCatch
(如下面的代码中)来实现,但有没有更好的方法来做到这一点?
I found a way to catch warnings using withCallingHandlers
(described here). However, I need to catch errors as well. I can do it by wrapping it in a tryCatch
(as in the code below), but is there a better way to do it?
catchToList <- function(expr) {
val <- NULL
myWarnings <- NULL
wHandler <- function(w) {
myWarnings <<- c(myWarnings, w$message)
invokeRestart("muffleWarning")
}
myError <- NULL
eHandler <- function(e) {
myError <<- e$message
NULL
}
val <- tryCatch(withCallingHandlers(expr, warning = wHandler), error = eHandler)
list(value = val, warnings = myWarnings, error=myError)
}
这个函数的输出示例是:
Sample output of this function is:
> catchToList({warning("warning 1");warning("warning 2");1})
$value
[1] 1
$warnings
[1] "warning 1" "warning 2"
$error
NULL
> catchToList({warning("my warning");stop("my error")})
$value
NULL
$warnings
[1] "my warning"
$error
[1] "my error"
SO 上有几个问题讨论了 tryCatch
和错误处理,但我发现没有一个问题可以解决这个特定问题.请参阅如何检查函数调用是否导致警告?、warnings() 在函数中不起作用?如何解决这个问题?,以及如何告诉 lapply 忽略错误并处理列表中的下一件事?a> 用于最相关的.
There are several questions here on SO that discuss tryCatch
and error handling, but none that I found that address this particular issue. See How can I check whether a function call results in a warning?, warnings() does not work within a function? How can one work around this?, and How to tell lapply to ignore an error and process the next thing in the list? for the most relevant ones.
推荐答案
也许这和你的解决方案一样,但我写了一个 factory
将普通的旧函数转换成捕获它们值的函数,错误和警告,所以我可以
Maybe this is the same as your solution, but I wrote a factory
to convert plain old functions into functions that capture their values, errors, and warnings, so I can
test <- function(i)
switch(i, "1"=stop("oops"), "2"={ warning("hmm"); i }, i)
res <- lapply(1:3, factory(test))
结果的每个元素都包含值、错误和/或警告.这适用于用户函数、系统函数或匿名函数(factory(function(i) ...)
).这里是工厂
with each element of the result containing the value, error, and / or warnings. This would work with user functions, system functions, or anonymous functions (factory(function(i) ...)
). Here's the factory
factory <- function(fun)
function(...) {
warn <- err <- NULL
res <- withCallingHandlers(
tryCatch(fun(...), error=function(e) {
err <<- conditionMessage(e)
NULL
}), warning=function(w) {
warn <<- append(warn, conditionMessage(w))
invokeRestart("muffleWarning")
})
list(res, warn=warn, err=err)
}
以及一些处理结果列表的助手
and some helpers for dealing with the result list
.has <- function(x, what)
!sapply(lapply(x, "[[", what), is.null)
hasWarning <- function(x) .has(x, "warn")
hasError <- function(x) .has(x, "err")
isClean <- function(x) !(hasError(x) | hasWarning(x))
value <- function(x) sapply(x, "[[", 1)
cleanv <- function(x) sapply(x[isClean(x)], "[[", 1)
这篇关于如何将警告和错误保存为函数的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!