Comment vérifier l'existence d'un argument d'entrée pour les fonctions R

J'ai une fonction définie comme

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(...)
}

Dans cette fonction, je veux vérifier si l'utilisateur entre "z" dans la liste des arguments. Comment puis-je le faire? J'ai essayé exists("z"), missing("z"), et get("z") et aucun d'entre eux travaille.

31
demandé sur danioyuan 2012-03-26 22:02:11

4 réponses

@Sacha Epskamp a une très bonne solution, mais cela ne fonctionne pas toujours. Le cas où il échoue est si l'argument "z" est passé comme 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
29
répondu Tommy 2012-03-26 18:34:19

Je pense que vous cherchez simplement hasArg

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

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

À Partir de ?hasArg:

L'expression hasArg(x), par exemple, est similaire à !manquant(x), avec deux exceptions près. Tout d'abord, hasArg recherchera un argument nommé x dans le appelez si x n'est pas un argument formel à la fonction appelante, mais ... être. Deuxièmement, hasArg ne génère jamais d'erreur si on lui donne un nom en tant que argument, alors que missing (x) génère une erreur si x n'est pas un argument.

52
répondu GSee 2012-03-27 20:04:19

Il peut y avoir des cas où vous ne voudrez peut-être pas appeler list(...), car cela évaluera toutes les expressions dans les points. Par exemple,

myFun <- function(x, y, ...){
  myArgs <- list(...)
  zInArgs <- ("z" %in% names(myArgs))
  return(zInArgs)
}

myFun(x = 2, y = "Happy", z = list(rep(rnorm(2e6), 100)))

Cela prendra beaucoup de temps. Au lieu de cela, utilisez 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)))

Le premier exemple est toujours sur ma machine, tandis que le second exemple ne devrait prendre pratiquement pas de temps.

Modifier:

Pour répondre au commentaire de @ 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
8
répondu BenBarnes 2012-03-27 13:11:01

Voici une façon dont je le fais souvent. Convertissez d'abord ... en liste, puis vérifiez si les éléments ne sont pas NULL:

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

Quelques résultats:

> myFun()
[1] FALSE
> myFun(z=1)
[1] TRUE
4
répondu Sacha Epskamp 2012-03-26 18:15:24