返回所有错误

Returning all errors

提问人:Andrea 提问时间:11/16/2023 最后编辑:Konrad RudolphAndrea 更新时间:11/17/2023 访问量:61

问:

假设我有以下函数结构(我实际问题的简化版本):

simple_function <- function(x, y) {
  if (!is.numeric(x) && is.numeric(y)) {
    stop("x must be a number")
  }
  else if (!is.numeric(y)) {
    stop("y must be a number")
  }
  else if (is.numeric(x) && is.numeric(y)) {
    result <- sub_fun(x, y)
  }
  return(result)
}

sub_func <- function(x) {
  if (x > 5) {
    result <- x * y
  }
  else if (x < 5) {
    result <- x + y
  }
  else if (x == 5) {
    stop ("x cannot be equal to 5.")
  }
  return(result)
}

a = 5
b = 'b'
> simple_function(a, b) : y must be a number

有没有办法以这样一种方式运行函数,即我得到两个相关的停止错误,如果它没有在第一个停止时退出,y 必须是一个数字,这些错误就会运行?

R 函数 错误处理

评论

3赞 Dirk Eddelbuettel 11/16/2023
请考虑删除代码示例中过多的空格。如果我们可以在不滚动的情况下看到所有代码,那对我们来说会更容易。
2赞 MrFlick 11/16/2023
当您调用 时,就是这样:函数结束。不再运行任何代码。如果这不是您想要的,则在某种列表中收集错误,并且仅当该列表不为空时,才调用 stop 并将所有错误组合在一起。R 只允许一次抛出一个错误。stop()
0赞 Konrad Rudolph 11/17/2023
...你走得太远了:一些空格增加了可读性。问题在于所有行之间有空行,没有明智的空格来构建代码流。
0赞 Konrad Rudolph 11/17/2023
关于你的问题,我认为你的想法太复杂了:如果你的函数有应该检查的前提条件,请在单个表达式中检查它们并报告相应的错误。— 当然,您可以任意详细地显示错误消息。但通常,“零碎”报告错误也没有问题,即只停留在第一个问题上。最终用户 UI 可能不应该这样做,但对于编程 API 来说,这是完全约定俗成的,通常就足够了。

答:

3赞 Limey 11/17/2023 #1

评论者已经解释了为什么你不能(轻松)在基础 R 中做你想做的事。

该软件包允许您执行类似于您想要的事情。下面是代码的变体,更正了几个拼写错误。checkmate

library(checkmate)

simple_function <- function(x, y) {
  allErrors <- makeAssertCollection()
  assertNumeric(x, len = 1, add = allErrors)
  assertNumeric(y, len = 1, add = allErrors)
  
  sub_func(x, y, allErrors)
}

sub_func <- function(x, y, collection) {
  assertFALSE(x == 5, add = collection)
  reportAssertions(collection)
  
  ifelse(x > 5,  x * y, x + y)
}

a = 5
b = 'b'

simple_function(a, b) 

Error in simple_function(a, b) : 2 assertions failed:
* Variable 'y': Must be of type 'numeric', not 'character'.
* Variable 'x == 5': Must be FALSE.

但是,在更复杂的实际示例中,在检测到错误后允许代码继续可能会导致更复杂的代码。我不建议允许将一个函数的错误输入传递给其他函数。