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

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

问题描述

我正在使用 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屋!

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