Подтвердить что ты не робот

Как проверить наличие входного аргумента для функций R

У меня есть функция, определенная как

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"), и никто из них не работает.

4b9b3361

Ответ 1

@Sacha Epskamp имеет довольно хорошее решение, но оно не всегда работает. Случай, когда он терпит неудачу, заключается в том, что аргумент "z" передается как NULL...

# Sacha 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

Я думаю, вы просто ищете hasArg

myFun <- function(x, y, ...) { 
  hasArg(z)
}

> myFun(x=3, z=NULL)
[1] TRUE

От ?hasArg:

Выражение hasArg (x), например, похоже на! missing (x), с два исключения. Во-первых, hasArg будет искать аргумент с именем x в вызов, если x не является формальным аргументом вызывающей функции, но... является. Во-вторых, hasArg никогда не генерирует ошибку, если задано имя как аргумент, тогда как отсутствует (x) генерирует ошибку, если x не является формальным аргумент.

Ответ 3

Бывают случаи, когда вы не хотите вызывать 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)))

Первый пример все еще прерывается на моей машине, в то время как второй пример практически не требует времени.

EDIT:

Чтобы ответить на комментарий от @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

Вот как я часто это делаю. Сначала преобразуйте ... в список, затем проверьте, не являются ли элементы NULL:

myFun <- function(x, y, ...) { 
args <- list(...)
exist <- !is.null(args[['z']])
return(exist)
}

Некоторые результаты:

> myFun()
[1] FALSE
> myFun(z=1)
[1] TRUE