[英]Making informative `stopifnot()` errors using NSE in R
我想做出信息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)
输出给出了这个(不是那么有用)
错误:eval(bquote(。(x)%in%e [[。(z)]]))不正确
我希望这个错误能提供更多信息,例如:
错误:5%in%e [[“” label“]]不正确
我该如何工作? 还是实现我想要的最好的方法是什么
我知道我可以编写一个if条件不为真,然后打印我自己的错误作为替代,但是额外的代码很麻烦。 我想了解如何让NSE使其正常工作。
编辑:这种方法的动机来自阅读hadley的评论(位于http://r-pkgs.had.co.nz/tests.html ):
但是,如果期望失败,则不会给出非常有用的输出:
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
相反,您可以使用一些非标准评估来产生更多信息。 关键是使用bquote()和eval()。 在下面的bquote()调用中,请注意..x的用法-()的内容将插入到调用中。
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
CRAN上有许多软件包可以解决有意义的错误消息的问题。 我从assertthat
和assertive
包开始,但是现在使用checkmate
来生产代码,尤其是用于检查函数的参数。 顺便说一句, checkmate
也延伸哈德利的testthat
包。
与checkmate
,
checkmate::assert_choice(5, e[["label"]])
返回错误信息:
checkmate :: assert_choice(5,e [[“” label“]])中的错误:
对'5'的声明失败:必须是集合{'1','2','3'}的元素。
也可以在功能中使用
check_in_y <- function(x, z, e) {
checkmate::assert_choice(x, e[[z]])
}
check_in_y(5, "label", e)
返回相同的错误消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.