如何检查R函数输入参数的存在性

时间:2022-11-25 16:53:20

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