3

我正在尝试创建一个将评估表达式的函数,如果该表达式的结果不是“有限”(由 is.finite 定义),那么它将返回一个默认值。如果抛出错误,该函数仍应返回默认值。该函数也应该被矢量化。

这应该很简单,但我只是不完全理解 R 的错误捕获功能。有人可以帮助改进/简化此功能以满足这些测试用例吗?

这是我拥有的功能的开始。即使它会起作用,它也相当丑陋。

getOrElse <- function (expr, default = 0) {

    # protect against any errors
    val <- tryCatch (expr, error = function (e) {})

    # replace any non-finite values
    val [!is.finite(val)] <- default

    # this is really ugly
    if (length(val) > 1 && !is.finite(val)) val <- default

    return (val)
}

这里是“测试用例”......

getOrElse (sqrt(4), default = 10) == 2 # WORKS

getOrElse (stop ("ignore"), default = 10) == 10  # BROKEN

getOrElse (sqrt(c(4, 16, NA, NaN)), default = 0) == c(2, 4, 0, 0) # BROKEN

getOrElse (sqrt(c(4, 16)), default = 0) == c(2, 4)  # WORKS

getOrElse (c(NA, NA), default = 10) == c(10, 10)  # WORKS

非常感谢

4

1 回答 1

3

当您遇到错误时,您实际上并没有做任何事情,因此请考虑以下修改:

getOrElse <- function (expr, default = 0) {
    stopifnot(length(default) == 1)
    val <- tryCatch (expr, error = function (e) {})
    if( length(val) ){
         val [!is.finite(val)] <- default
      } else { 
         val <- default}

    return (val)
}

它仍然会使您的测试失败,getOrElse (sqrt(c(4, 16, NA, Nan)), default = 0) == c(2, 4, 0, 0)但那是因为Nan不是NaN,上面的代码将返回长度为 1 的“默认”值。如果您改用getOrElse (sqrt(c(4, 16, NA, NaN)), default = 0) == c(2, 4, 0, 0)它的测试将成功。如果您仍然需要在分别应用于函数的每个参数的表达式中返回函数,那么您将需要进行更复杂的解析。

于 2013-11-08T18:14:03.487 回答