我正在尝试创建一个将评估表达式的函数,如果该表达式的结果不是“有限”(由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
非常感谢
答案 0 :(得分: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
不是getOrElse (sqrt(c(4, 16, NA, NaN)), default = 0) == c(2, 4, 0, 0)
,上面的代码会返回长度为1且带有'default'值。如果您使用{{1}}进行测试,则会成功。如果仍然要求将单独应用的表达式中的函数返回到函数的每个参数,那么您将需要执行更复杂的deparsing。