我想要提供信息丰富的 stopifnot()
错误。
我读过: http://r-pkgs.had.co.nz/tests.html (最后关于使用 NSE 为示例打印出信息性测试错误的部分似乎相关) 和 http://adv-r.had.co.nz/Computing-on-the-language.html 但我不能让它在简洁的代码中打印一个信息性错误:
e <- new.env()
e$label <- c(1,2,3)
check_in_y <- function(x, z, e) {
stopifnot(eval(bquote(.(x) %in% e[[.(z)]])))
}
check_in_y(5,"label", e)
输出给出了这个(信息量不大)
Error: eval(bquote(.(x) %in% e[[.(z)]])) is not TRUE
我希望错误信息更丰富,这样说:
Error: 5 %in% e[["label"]] is not TRUE
我怎样才能让它工作?或者实现我想要的最佳方法是什么
我知道我可以编写一个 if condition not true 然后打印我自己的错误作为替代,但是额外的代码很麻烦。我想了解如何让 NSE 让它发挥作用。
编辑: 我采用这种方法的动机来自阅读 hadley 的评论(位于 http://r-pkgs.had.co.nz/tests.html):
However, if the expectation fails this doesn’t give very informative output:
expect_floor_equal("year", "2008-01-01 00:00:00") ## Error: floor_date(base, unit) not equal to as.POSIXct(time, tz = "UTC") ## Mean absolute difference: 31622400
Instead you can use a little non-standard evaluation to produce something more informative. The key is to use bquote() and eval(). In the bquote() call below, note the use of .(x) - the contents of () will be inserted into the call.
expect_floor_equal <- function(unit, time) { as_time <- function(x) as.POSIXct(x, tz = "UTC") eval(bquote(expect_equal(floor_date(base, .(unit)), as_time(.(time))))) } expect_floor_equal("year", "2008-01-01 00:00:00") ## Error: floor_date(base, "year") not equal to as_time("2008-01-01 00:00:00")
最佳答案
stopifnot
只是
if(!all(condition)) stop(standard message)
对于自定义消息,只需编写代码。您可以用两行替换 stopifnot
调用:
check_in_y <- function(x, z, e) {
b <- bquote(.(x) %in% e[[.(z)]])
if(!eval(b)) stop(deparse(b), " is not TRUE", call. = FALSE)
}
check_in_y(5, "label", e)
# Error: 5 %in% e[["label"]] is not TRUE
关于r - 在 R 中使用 NSE 生成信息丰富的 `stopifnot()` 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43395620/