如何将警告和错误作为函数的输出保存? [英] How do I save warnings and errors as output from a function?

查看:96
本文介绍了如何将警告和错误作为函数的输出保存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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 捕获警告的方法(在此描述:https://stackoverflow.com/questions/4947528 )。但是,我也需要捕获错误。我可以通过将它包装在一个 tryCatch (如下面的代码)中,但是有没有更好的方法?

I found a way to catch warnings using withCallingHandlers (described here: https://stackoverflow.com/questions/4947528). 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)
} 

此函数的示例输出是:

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

这里有几个问题,讨论 tryCatch 和错误处理,但是我没有找到解决这个特定问题的问题。请参阅如何检查函数调用是否导致警告? warnings()在函数内不起作用?如何解决这个问题?如何告诉您是否忽略错误并处理列表中的下一件事?一个>最相关的。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆