更好的错误消息为stopifnot?

时间:2011-12-01 15:07:32

标签: r

我正在使用stopifnot,我理解它只返回第一个不是TRUE的值。我是一个怪异的动态表达,没有进入自定义功能的人无法真正做出一些东西。所以我很乐意添加自定义错误消息。有什么建议吗?

Error: length(unique(nchar(check))) == 1 is not TRUE

基本上声明向量check的元素长度不同。 有没有办法说:Error: Elements of your input vector do not have the same length!

7 个答案:

答案 0 :(得分:32)

使用stopif声明:

if(length(unique(nchar(check))) != 1) 
  stop("Error: Elements of your input vector do not have the same length!")

请记住,stopifnot有说明否定的便利,因此if中的条件需要取消你的停止条件。


这是错误消息的样子:

> check = c("x", "xx", "xxx")
> if(length(unique(nchar(check))) != 1) 
+   stop("Error: Elements of your input vector do not have the same length!")

Error in eval(expr, envir, enclos) : 
  Error: Elements of your input vector do not have the same length!

答案 1 :(得分:12)

assertiveassertthat包具有更易读的检查功能。

library(assertthat)
assert_that(length(unique(nchar(check))) == 1)
## Error: length(unique(nchar(check))) == 1 are not all true.

library(assertive)
assert_is_scalar(unique(nchar(check)))
## Error: unique(nchar(check)) does not have length one.

if(!is_scalar(unique(nchar(check)))) 
{
  stop("Elements of check have different numbers of characters.")
}
## Error: Elements of check have different numbers of characters.

答案 2 :(得分:5)

或者你可以打包它。

assert <- function (expr, error) {
  if (! expr) stop(error, call. = FALSE)
}

所以你有:

> check = c("x", "xx", "xxx")
> assert(length(unique(nchar(check))) == 1, "Elements of your input vector do not have the same length!")

Error: Elements of your input vector do not have the same length!

答案 3 :(得分:4)

如何将stopifnot嵌入到tryCatch中,然后使用自定义消息使用stop重新构建例外?

类似的东西:

tryCatch(stopifnot(...,error=stop("Your customized error message"))

与其他一些解决方案不同,这不需要额外的包。与使用if语句结合stop相比,当您使用新的R版本时,保留了stopifnot的性能优势。由于R版本3.5.0 stopifnot按顺序计算表达式并在第一次失败时停止。

答案 4 :(得分:1)

我建议你查看Hadley的testthat包裹。它允许直观的测试:函数的名称很棒,你编写它们的方式就像一个句子 - “我希望length(unique(nchar(check)))是[完全|大约] 1”。产生的错误是有益的。

见这里: http://journal.r-project.org/archive/2011-1/RJournal_2011-1_Wickham.pdf

在你的情况下,

> library(testthat)
> check = c("x", "xx", "xxx")
> expect_that(length(unique(nchar(check))), equals(1))
Error: length(unique(nchar(check))) not equal to 1
Mean relative difference: 2

另请注意,您没有@Andrie引用的问题,有时不得不考虑stopifnot的双重否定。我知道这看起来很简单,但这让我很头疼!

答案 5 :(得分:1)

已经提供的答案非常好,我的只是该系列的补充。对于某些人来说,以下列功能的形式使用单线程可能更方便:

stopifnotinform <- function(..., message = "err") {
  args <- list(...)
  if (length(args) == 0) {
    return(NULL)
  }
  for (i in 1:length(args)) {
    result <- args[[i]]
    if (is.atomic(result) && result == FALSE) {
      stop(message)
    }
  }
}

# throws an error
stopifnotinform(is.integer(1L), is.integer(2), message = "Some number(s) provided is not an integer")
# continues with execution
stopifnotinform(is.integer(1L), is.integer(2L), message = "Some number(s) provided is not an integer")

请记住,此解决方案只为...中的所有参数提供了一条(常见)错误消息。

答案 6 :(得分:1)

可以将自定义消息作为标签添加到您的表达式中:

stopifnot("Elements of your input vector do not have the same length!" =
  length(unique(nchar(check))) == 1)

# Error: Elements of your input vector do not have the same length!