警告而不是assert_that()的错误?

时间:2015-07-01 01:20:21

标签: r assertions assertthat

我正在使用R的断言包并且我想(暂时)输出警告而不是断言失败的错误。使用assertthat包最简单的方法是什么?

我意识到想要警告而不是错误类似于断言应该用于什么。从长远来看,我们确实希望在断言失败时输出错误。在短期内,我们仍然希望代码即使输入错误也能正常工作,因为输入错误的输出现在仍然“足够好”。

一个简单的例子:假设我有一个函数,它将x作为输入并输出x + 5。如果x!= 3,我想输出警告。由于我们最终会使用assert_that,如果我们可以使用assertthat包进行警告,那就太好了。

从长远来看,我们将使用它:

> x <- 3
> fn <- function(x) {assert_that(x==3); return(x+5)}
> fn(3)
[1] 8
> fn(4)
 Error: x not equal to 3 

在短期内,这是我迄今为止最好的:

> fn <- function(x) {if(!see_if(x==3)) warning(validate_that(x==3)); return(x+5)}
> fn(3)
[1] 8
> fn(4)
[1] 9
Warning message:
In fn(4) : x not equal to 3

我正在寻找一个更简洁的解决方案,如果可能的话(最好的情况是将“output_warning”参数传递给assert_that,但我认为不存在)。

4 个答案:

答案 0 :(得分:3)

我创建了一个用户定义的函数,该函数接受与您希望运行validate_that()(最终assert_that())的表达式相对应的字符串。如果断言失败,该函数将打印警告,否则保持静默。请参阅下面的使用方法如有必要,您可以轻松扩展此自定义函数以接受多个表达式。请注意,我还使用sys.calls()来获取调用此帮助函数的函数的名称。这是一条重要的信息,因此您可以将警告与实际生成它们的代码相关联。

assert_that_soft <- function(exp) {
                        if (!exp) {
                            print (paste("Error in function:",
                                   parse(sys.calls()[[sys.nframe()-1]])) ) # name of caller
                        }
                    }

<强>用法:

> fn <- function(x) { assert_that_soft(x==3); return(x+5) }
> fn(3)
[1] 8
> fn(8)
[1] "Error in function: fn(8)"
[1] 13

答案 1 :(得分:1)

我认为覆盖该函数的最简单方法是按原样复制大部分assert_that函数,并使用相同名称调用新函数,这样您就不需要更改所有代码当你进入错误模式时。

assert_that <- function(..., env=parent.frame()) {
    res <- see_if(..., env=env)
    if (res)
        return(TRUE)
    warning(attr(res, "msg"))
    TRUE
}

fn <- function(x) { assert_that(x==3); return(x+5) }
fn(3)
# [1] 8
fn(8)
# [1] 13
# Warning message:
# In assert_that(x == 3) : x not equal to 3

答案 2 :(得分:0)

另一种选择是将assert_that包装在tryCatch中。

fn <- function(x) tryCatch(assert_that(x == 3), error = function(e) warning(e), finally = return(x+5))
fn(3)
# [1] 8
fn(8)
# [1] 13
# Warning message:
# x not equal to 3

答案 3 :(得分:0)

我提议扩展 assertthat 包以允许简单的警告,请参阅 https://github.com/hadley/assertthat/issues/69 欢迎任何反馈!