I have a function defined as
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(...)
}
In this function, I want to check whether user input "z" in the argument list. How can I do that? I tried exists("z")
, missing("z")
, and get("z")
and none of them works.
@Sacha Epskamp has a pretty good solution, but it doesn't always work. The case where it fails is if the "z" argument is passed in as 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
I think you're simply looking for hasArg
myFun <- function(x, y, ...) {
hasArg(z)
}
> myFun(x=3, z=NULL)
[1] TRUE
From ?hasArg
:
The expression hasArg(x), for example, is similar to !missing(x), with two exceptions. First, hasArg will look for an argument named x in the call if x is not a formal argument to the calling function, but ... is. Second, hasArg never generates an error if given a name as an argument, whereas missing(x) generates an error if x is not a formal argument.
There might be instances when you might not want to call list(...)
, since this will evaluate all the expressions in the dots. For example,
myFun <- function(x, y, ...){
myArgs <- list(...)
zInArgs <- ("z" %in% names(myArgs))
return(zInArgs)
}
myFun(x = 2, y = "Happy", z = list(rep(rnorm(2e6), 100)))
This will take a long time. Instead, use 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)))
The first example is still chugging away on my machine, while the second example should take practically no time at all.
EDIT:
To answer the comment from @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
Here is a way I often do it. First convert ...
to a list, then check if the elements are not NULL
:
myFun <- function(x, y, ...) {
args <- list(...)
exist <- !is.null(args[['z']])
return(exist)
}
Some results:
> myFun()
[1] FALSE
> myFun(z=1)
[1] TRUE
来源:https://stackoverflow.com/questions/9877271/how-to-check-existence-of-an-input-argument-for-r-functions