dan*_*uan 34 arguments r function exists
我有一个定义为的函数
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(...)
}
Run Code Online (Sandbox Code Playgroud)
在这个函数中,我想检查用户是否在参数列表中输入"z".我怎样才能做到这一点?我想exists("z"),missing("z")和get("z")他们都不工作.
GSe*_*See 60
我想你只是在寻找 hasArg
myFun <- function(x, y, ...) {
hasArg(z)
}
> myFun(x=3, z=NULL)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)
来自?hasArg:
例如,表达式hasArg(x)类似于!missing(x),但有两个例外.首先,如果x不是调用函数的正式参数,hasArg将在调用中查找名为x的参数,但是...是.其次,如果将名称作为参数,hasArg从不生成错误,而如果x不是正式参数,则missing(x)会生成错误.
Tom*_*mmy 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
Run Code Online (Sandbox Code Playgroud)
可能存在您可能不想调用的情况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)))
Run Code Online (Sandbox Code Playgroud)
这将需要很长时间.相反,使用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)))
Run Code Online (Sandbox Code Playgroud)
第一个例子仍在我的机器上,而第二个例子几乎没有时间.
编辑:
要回答@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
Run Code Online (Sandbox Code Playgroud)
这是我经常做的一个方法。首先转换...为列表,然后检查元素是否不是NULL:
myFun <- function(x, y, ...) {
args <- list(...)
exist <- !is.null(args[['z']])
return(exist)
}
Run Code Online (Sandbox Code Playgroud)
一些结果:
> myFun()
[1] FALSE
> myFun(z=1)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)