前段时间我创建了一个函数,用于检查参数是否缺失,如果是,则返回信息性错误。它看起来像这样:
#' Check if arguments are missing and raise error if they are
#'
#' Checks if arguments are missing and raises an error if they are. Put this in the beginning of your functions to check the input and give useful errors without writing checking code over and over again.
#' @param var_names (chr vector) Names of variables to check.
#' @param error_msg (chr scalar) A template of the error message to show.
#' @export
#' @examples
#' test_func = function(y) {
#' check_missing("y")
#' T
#' }
#' test_func(y = ) #throws error
#' test_func(y = 1) #returns true
check_missing = function(var_names, error_msg = "[VAR] was missing! Please supply the input and try again.") {
#parent.frame as list
pf = as.list(parent.frame())
#check each if missing
for (name in var_names) {
#is it there at all?
if (!name %in% names(pf)) {
stop(name + " is not even found in the parent.frame! Check the variable names.", call. = F)
}
#check if missing
if (are_equal(pf[[name]], quote(expr = ))) {
stop(str_replace(error_msg, pattern = "\\[VAR\\]", name), call. = F)
}
}
#all fine
return(invisible(NULL))
}
来自this package的功能,用于:
library(devtools);install_github("deleetdk/kirkegaard");library("kirkegaard")
在一个特定的用例中,我得到一个列表作为传递给上面检查函数的参数。但是,这导致:
Error in all.equal.list(target, current, ...) :
argument "current" is missing, with no default
可以用这个最小的例子重现这一点:
> all.equal(list(), quote(expr = ))
Error in all.equal.list(list(), quote(expr = )) :
argument "current" is missing, with no default
base-r函数中是否存在错误,或者我误解了某些内容?
我通过插入以下内容来解决问题:
if (is.list(pf[[name]])) return(invisible(NULL)) #evade bug?
在违规行之前(对are_equal
的调用,all.equal
的包装。)
答案 0 :(得分:1)
如果使用identical
代替,问题应该会消失
all.equal
。
首先,请注意quote(expr = )
会创建一个丢失的对象:
test_env <- new.env()
test_env$a <- quote(expr = )
ls.str(test_env)
a : <missing>
接下来,请注意all.equal
在两个参数都正常工作
缺少,但只有其中一个缺失时失败。
all.equal(target = quote(expr = ), current = test_env$a)
[1] TRUE
all.equal(target = list(), current = test_env$a)
Error in all.equal.list(target = list(), current = test_env$a) :
argument "current" is missing, with no default
原因是all.equal
首先检查参数
是相同的 - 如果没有,它会尝试做更多的事情
比较(详见?all.equal
)。
如果使用identical
代替,则不存在此问题
all.equal
:
identical(x = quote(expr = ), y = test_env$a)
[1] TRUE
identical(x = list(), y = test_env$a)
[1] FALSE
基于此,我猜你的代码应该可以替换
(are_equal(pf[[name]], quote(expr = )))
(identical(pf[[name]], quote(expr = )))
。