【问题标题】:R: Creating a custom error message giving argument values for a function in a packageR:创建自定义错误消息,为包中的函数提供参数值
【发布时间】:2018-07-23 06:24:21
【问题描述】:

假设有一组函数,从不是我编写的包中提取,我想分配给错误时的特殊行为。我目前关心的是 dplyr 中的 _impl 系列函数。以 mutate_impl 为例。当我从 mutate 收到错误时,回溯几乎总是将我带到 mutate_impl,但这通常是调用堆栈的一种方式——我已经看到它从调用 mutate 中调用了多达 15 个调用。所以我当时想知道的通常是 mutate_impl 的参数与我最初提供给 mutate 的参数之间的关系(或认为我做了)。

所以,这段代码可能在很多方面都错了——当然它不起作用——但我希望它至少有助于表达我的意图。这个想法是我可以将它包装在 mutate_impl 周围,如果它产生错误,它会保存错误消息和参数描述并将它们作为列表返回

str_impl  <- function(f){tryCatch(f, error = function(c) {
    msg <- conditionMessage(c)
    args <- capture.output(str(as.list(match.call(call(f)))))
    list(message =  msg, arguments = args)
}
assign(str_impl(mutate_impl), .GlobalEnv)

尽管如此,这仍然没有达到我真正想要的效果,因为即使没有工作代码的限制,我也无法弄清楚如何制作草稿。我真正想要的是能够识别一个函数或函数列表,我希望在错误时具有此行为,然后无论何时何地调用该函数时都会发生错误。如果不重写 dplyr 包环境中的函数,我什至想不出任何方法来开始这样做,这让我觉得这是一个非常糟糕的主意。

对全局环境的最终分配应该将错误对象返回到我可以找到它的地方,即使对 mutate_impl 的调用发生在无法访问的地方,例如在错误之后不再存在的环境中。

【问题讨论】:

    标签: r function debugging dplyr metaprogramming


    【解决方案1】:

    可能实现您想要的最佳方式是通过trace 功能。确实值得阅读有关 trace 的帮助,但这里有一个工作示例:

    library(dplyr)
    
    trace("mutate_impl", exit = quote({
      if (class(returnValue())[1]=="NULL") {
        cat("df\n")
        print(head(df))
        cat("\n\ndots\n")
        print(dots)
      } else {
        # no problem, nothing to do
      }
    }), where = mutate, print = FALSE)
    
    # ok
    xx <- mtcars %>% mutate(gear = gear * 2)
    # not ok, extra output
    xx <- mtcars %>% mutate(gear = hi * 2)
    

    根据您的特定需求进行调整应该相当简单,例如如果您想登录到文件

    trace("mutate_impl", exit = quote({
      if (class(returnValue())[1]=="NULL") {
        sink("error.log")
        cat("df\n")
        print(head(df))
        cat("\n\ndots\n")
        print(dots)
        sink()
      } else {
        # no problem, nothing to do
      }
    }), where = mutate, print = FALSE)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 2019-11-05
      • 2018-05-15
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多