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.
在这个函数中,我要检查用户是否在参数列表中输入“z”。我怎么做呢?我尝试了存在(z)、缺失(z)和获取(z),但没有一个有效。
4 个解决方案
#1
27
@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 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
51
I think you're simply looking for hasArg
我想你只是在找哈萨格
myFun <- function(x, y, ...) {
hasArg(z)
}
> myFun(x=3, z=NULL)
[1] TRUE
From ?hasArg
:
从? 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.
例如,表达式hasArg(x)与!missing(x)类似,只有两个例外。首先,如果x不是调用函数的正式参数,hasArg将在调用中查找一个名为x的参数,但是…是多少。其次,如果给定一个名称作为参数,hasArg不会生成错误,而如果x不是一个正式参数,则缺失(x)会生成错误。
#3
8
There might be instances when you might not want to call list(...)
, since this will evaluate all the expressions in the dots. For example,
在某些情况下,您可能不希望调用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)))
This will take a long time. Instead, use match.call()
:
这需要很长时间。相反,使用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:
回复@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
#4
4
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
#1
27
@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 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
51
I think you're simply looking for hasArg
我想你只是在找哈萨格
myFun <- function(x, y, ...) {
hasArg(z)
}
> myFun(x=3, z=NULL)
[1] TRUE
From ?hasArg
:
从? 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.
例如,表达式hasArg(x)与!missing(x)类似,只有两个例外。首先,如果x不是调用函数的正式参数,hasArg将在调用中查找一个名为x的参数,但是…是多少。其次,如果给定一个名称作为参数,hasArg不会生成错误,而如果x不是一个正式参数,则缺失(x)会生成错误。
#3
8
There might be instances when you might not want to call list(...)
, since this will evaluate all the expressions in the dots. For example,
在某些情况下,您可能不希望调用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)))
This will take a long time. Instead, use match.call()
:
这需要很长时间。相反,使用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:
回复@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
#4
4
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