来自 assert_that() 的警告而不是错误?
Warnings instead of errors from assert_that()?
我正在使用 R 的 assertthat 包,我想(暂时)在断言失败时输出警告而不是错误。使用 assertthat 包最简单的方法是什么?
我意识到想要警告而不是错误有点违背断言的用途。从长远来看,我们确实希望在断言失败时输出错误。在短期内,我们仍然希望代码即使在输入错误的情况下也能正常运行,因为输入错误的输出目前仍然是 "good enough"。
一个简单的例子:假设我有一个以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,但我认为不存在)。
我创建了一个用户定义的函数,它接受一个字符串,该字符串对应于您想要 运行 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
我认为覆盖该函数的最简单方法是按原样复制大部分 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
另一种选择是将 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
我提议扩展 assertthat 包以允许简单的警告,请参阅
https://github.com/hadley/assertthat/issues/69
欢迎任何反馈!
我正在使用 R 的 assertthat 包,我想(暂时)在断言失败时输出警告而不是错误。使用 assertthat 包最简单的方法是什么?
我意识到想要警告而不是错误有点违背断言的用途。从长远来看,我们确实希望在断言失败时输出错误。在短期内,我们仍然希望代码即使在输入错误的情况下也能正常运行,因为输入错误的输出目前仍然是 "good enough"。
一个简单的例子:假设我有一个以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,但我认为不存在)。
我创建了一个用户定义的函数,它接受一个字符串,该字符串对应于您想要 运行 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
我认为覆盖该函数的最简单方法是按原样复制大部分 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
另一种选择是将 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
我提议扩展 assertthat 包以允许简单的警告,请参阅 https://github.com/hadley/assertthat/issues/69 欢迎任何反馈!