R:检查是否提供了必需/必需的参数
我希望能够有一种方法来检查在R中调用函数时没有指定默认值的所有参数。对我来说,这似乎是一件明智的事情,因为它可以避免在发现缺少值时函数在以后失败(这可能是在大量处理之后) 完成此任务的一种方法是为每个参数编写R:检查是否提供了必需/必需的参数,r,arguments,R,Arguments,我希望能够有一种方法来检查在R中调用函数时没有指定默认值的所有参数。对我来说,这似乎是一件明智的事情,因为它可以避免在发现缺少值时函数在以后失败(这可能是在大量处理之后) 完成此任务的一种方法是为每个参数编写if(missing(arg))语句,但这需要保持函数的参数和上述语句彼此一致,因此我正在寻找更好的解决方案 目前,我使用以下函数,它在大多数情况下都有效,但不是所有情况下都有效 # check for required arguments by getting arguments for
if(missing(arg))
语句,但这需要保持函数的参数和上述语句彼此一致,因此我正在寻找更好的解决方案
目前,我使用以下函数,它在大多数情况下都有效,但不是所有情况下都有效
# check for required arguments by getting arguments for the
# definition of the calling function and comparing to the arguments
# in the function call
check_required_args <- function () {
def <- sys.function(-1)
f_args <- formals(def)
f_args <- f_args[sapply(f_args, is.name)] # remove arguments with defaults
f_args <- names(f_args)
f_args <- f_args[f_args != '...'] # remove ellipsis argument if present
call <- match.call(definition=def, call=sys.call(-1))
f_name <- call[1]
c_args <- names(as.list(call[-1]))
for(n in f_args) {
if (!n %in% c_args) {
stop("Argument '", n, "' missing from call to function ",
f_name, "()", call.=FALSE)
}
}
}
f <- function(a, b, c=2) check_required_args()
f(a=1) # should fail (missing argument b)
f(2, 3) # should work
f(2, c=5) # should fail (missing argument b)
f(2, 3, 4) # should work
f <- function(a, b, ...) f2(a, b, ...)
f2 <- function(a, b, c, ...) check_required_args()
f2(a=1, b=2, c=3) # should work
f2(a=1, b=2) # should fail (missing argument c for function f2)
f(a=1, b=2, c=3) # should work
f(a=1, b=2) # should fail (missing argument c for function f2)
#通过获取
#调用函数的定义以及与参数的比较
#在函数调用中
检查所需参数可能是这个
check_required_args <- function (fun = sys.function(-1), ncall = 3) {
f_args <- formals(fun)
f_args <- f_args[vapply(f_args, is.symbol, FUN.VALUE = TRUE)]
f_args <- names(f_args)
f_args <- setdiff(f_args, "...")
test <- vapply(f_args,
function(x) missingArg(as.name(x), envir = parent.frame(ncall), eval = TRUE),
FUN.VALUE = TRUE)
stopifnot(!any(test))
return(invisible(NULL))
}
f <- function(a, b, c=2) {
check_required_args()
return("Hello!")
}
f(a=1) # should fail (missing argument b)
#Error: !any(test) is not TRUE
f(2, 3) # should work
#[1] "Hello!"
f(2, c=5) # should fail (missing argument b)
# Error: !any(test) is not TRUE
f(2, 3, 4) # should work
#[1] "Hello!"
x <- 1
f(a=x, 3)
#[1] "Hello!"
f <- function(a, b, ...) f2(a, b, ...)
f2 <- function(a, b, c, ...) {
check_required_args()
return("Hello!")
}
f2(a=1, b=2, c=3) # should work
#[1] "Hello!"
f2(a=1, b=2) # should fail (missing argument c for function f2)
#Error: !any(test) is not TRUE
f(a=1, b=2, c=3) # should work
#[1] "Hello!"
f(a=1, b=2) # should fail (missing argument c for function f2)
#Error: !any(test) is not TRUE
如果不希望签入封闭框架,请设置inherits=FALSE
为什么需要这样做?R
的惰性计算的一个优点是可以忽略不需要的参数。更不用说你把参数放在函数形式中的第一个原因就是使用它们!因此,对你的问题的正确答案是:不,这不是一件“明智”的事情。我有几个函数,其中一个参数直到函数的后面才被使用,此时函数会因为缺少参数而抛出一个错误。当函数需要几个小时才能运行时,这是非常烦人的,因此在某些情况下,我想在进一步计算之前检查是否指定了所有必需的参数。对我来说似乎是合理的?不,你似乎犯了一些基本的编程错误。首先,不要把太多的处理放在一个函数中,以至于需要很长时间才能运行:编写多个函数并将它们编写在一起。“良好”功能IMHO不需要大量输入参数;您可能需要考虑将(已验证的)数据集构建为<代码>列表>代码>变量。第二,在某个时候,你必须进行输入验证,不仅是为了存在,而且是为了正确的数据类型(例如字符和数字)。谢谢。我认为f(c=2)
也应该失败,但它通过了这里的测试?我不知道如何根据您的期望来修复它<代码>a
和b
在f2
中不缺失,但仅在f
中缺失。因此,签入f2
不能告诉您它们在f
中缺失。我是否正确理解您希望遵循调用堆栈并检查所有封闭函数?在f2
开头强制计算参数可能更容易。请注意,这可能会造成性能问题(特别是当参数可能是大对象时)。
check_required_args <- function (fun = sys.function(-1), ncall = 3) {
f_args <- formals(fun)
f_args <- f_args[vapply(f_args, is.symbol, FUN.VALUE=TRUE)]
f_args <- names(f_args)
f_args <- setdiff(f_args, "...")
test <- lapply(f_args,
function(x) {
get(x, envir = parent.frame(ncall), inherits = TRUE)
return(NULL)
})
#possibly use a for loop instead
#wrap in tryCatch for customized error messages
}
f <- function(a, b, ...) f2(a, b, ...)
f2 <- function(a, b, c, ...) {
check_required_args()
return("Hello!")
}
f(c=2)
#Error in get(x, envir = parent.frame(ncall), inherits = TRUE) :
# argument "a" is missing, with no default