我有一个定义为
的函数myFun <- function(x, y, ...) {
# using exists
if (exists("z")) { print("exists z!") }
# using missing
try(if (!missing("z")) { print("z is not missing!") }, silent = TRUE)
# using get
try(if (get("z")) { print("get z!") }, silent = TRUE)
# anotherFun(...)
}
在这个函数中,我想检查用户是否在参数列表中输入“z”。我怎样才能做到这一点?我尝试了exists("z")
,missing("z")
和get("z")
,但都没有。
答案 0 :(得分:59)
我认为你只是在寻找hasArg
myFun <- function(x, y, ...) {
hasArg(z)
}
> myFun(x=3, z=NULL)
[1] TRUE
来自?hasArg
:
表达式hasArg(x),例如,类似于!missing(x),with 两个例外。首先,hasArg将在中查找名为x的参数 如果x不是调用函数的正式参数,则调用,但是...... 是。其次,如果给出一个名称,hasArg永远不会生成错误 如果x不是正式的,则missing(x)会生成错误 参数。
答案 1 :(得分:30)
@Sacha Epskamp有一个非常好的解决方案,但它并不总是有效。它失败的情况是“z”参数是否为NULL ...
# Sacha's solution
myFun <- function(x, y, ...) {
args <- list(...)
exist <- !is.null(args[['z']])
return(exist)
}
myFun(x=3, z=NULL) # FALSE, but should be TRUE!
# My variant
myFun2 <- function(x, y, ...) {
args <- list(...)
exist <- "z" %in% names(args)
exist
}
myFun2(x=3, z=NULL) # TRUE
答案 2 :(得分:8)
可能存在您可能不想调用list(...)
的情况,因为这将评估点中的所有表达式。例如,
myFun <- function(x, y, ...){
myArgs <- list(...)
zInArgs <- ("z" %in% names(myArgs))
return(zInArgs)
}
myFun(x = 2, y = "Happy", z = list(rep(rnorm(2e6), 100)))
这需要很长时间。相反,请使用match.call()
:
myFun <- function(x, y, ...){
myArgs <- match.call()
zInArgs <- ("z" %in% names(myArgs))
return(zInArgs)
}
myFun(x = 2, y = "Happy", z = list(rep(rnorm(2e6), 100)))
第一个例子仍然在我的机器上,而第二个例子几乎没有时间。
修改强>
回答@CarlWitthoft的评论:
R> system.time(
+ (myAns <- myFun(x = 2, y = "Happy", z = list(rep(rnorm(2e6), 100))))
+ )
user system elapsed
0 0 0
R> myAns
[1] TRUE
答案 3 :(得分:4)
这是我经常这样做的方式。首先将...
转换为列表,然后检查元素是否不是NULL
:
myFun <- function(x, y, ...) {
args <- list(...)
exist <- !is.null(args[['z']])
return(exist)
}
一些结果:
> myFun()
[1] FALSE
> myFun(z=1)
[1] TRUE