Comment vérifier si un objet (variable) est défini dans R?


294

Je voudrais vérifier si une variable est définie dans R - sans obtenir d'erreur. Comment puis-je faire ceci?

Mes tentatives (infructueuses):

> is.na(ooxx)
Error: object 'ooxx' not found
> is.finite(ooxx)
Error: object 'ooxx' not found

Merci!

Réponses:


449

Vous voulez exists():

R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R> 

3
@Gavin & Dirk, vous êtes si gentils l'un avec l'autre :) La seule solution est que vous jetez la pièce (Bernoulli avec p = 0,5 :-)) qui obtiendra l'acceptation! :-)
— TMS

29
@tim si vous êtes dans une fonction, manquant () est ce que vous voulez.
— CousinCocaine

2
Pourrait être un peu plus compliqué si vous recherchez des éléments de liste: stackoverflow.com/q/7719741
— TMS

5
qu'en est-il de ce que l'op voulait - en utilisant le nom de la variable, pas entre guillemets?
— tim

109

Voir ?exists, pour une définition de "... est défini". Par exemple

> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE

7
Vous gagnez par 52 secondes :)
— Dirk Eddelbuettel

9
@DirkEddelbuettel Eh bien, si vous utilisez des noms d'objet ridiculement longs ;-)
— Gavin Simpson

2
il h. Cela m'arrive tout le temps quand je teste des exemples avant de poster, Gavin ou Josh y ont déjà répondu.
— Maiasaura

60

si vous êtes à l'intérieur d'une fonction, manquant () est ce que vous voulez.

exchequer = function(x) {
    if(missing(x)){
        message("x is missing… :-(")
    }
}

exchequer()
x is missing… :-(

missingne fonctionne que pour les arguments de fonction, cependant. Vous ne pouvez pas faire foo <- function(x) {missing(x); missing(y)}ou vous obtiendrez foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
— Dannid

46

Comme d'autres l'ont souligné, vous recherchez exists. Gardez à l'esprit que l'utilisation existsavec des noms utilisés par les packages de base de R retournerait vrai, que vous ayez défini ou non la variable:

> exists("data")
[1] TRUE

Pour contourner cela (comme l'a souligné Bazz; voir ?exists), utilisez l' inheritsargument:

> exists("data", inherits = FALSE)
[1] FALSE

foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE

Bien sûr, si vous vouliez rechercher les espaces de noms des packages attachés, cela serait également insuffisant:

> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE

La seule chose à laquelle je peux penser pour contourner cela - pour rechercher dans les packages joints mais pas dans les packages de base - est la suivante:

any(sapply(1:(which(search() == "tools:rstudio") - 1L),
           function(pp) exists(_object_name_, where = pp, inherits = FALSE)))

Comparer le remplacement _object_name_par "data.table"( TRUE) vs "var"( FALSE)

(bien sûr, si vous n'êtes pas sur RStudio, je pense que le premier environnement attaché automatiquement est "package:stats")


2
Jouer, utiliser l'argument inherits = FALSEsemble isoler les choses dans l'environnement mondial. Est-ce que ça sonne bien?
— CJB

1
@Bazz vous avez raison; J'ai édité ceci dans la réponse.
— MichaelChirico

2
Ce commentaire devrait être plus haut, puisque j'utilise le nom de variable "data", le simple fait d'exister m'a donné quelques problèmes au départ.
— mzm

25

Si vous ne voulez pas utiliser de guillemets, vous pouvez utiliser l' deparse(substitute())astuce que j'ai trouvée dans la section exemple de ?substitute:

is.defined <- function(sym) {
  sym <- deparse(substitute(sym))
  env <- parent.frame()
  exists(sym, env)
}

is.defined(a)
# FALSE
a <- 10
is.defined(a)
# TRUE

1
vous pouvez aussi forceou l'évaluer dans la fonction comme ceci:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
— chinsoon12

1

Il peut y avoir des situations dans lesquelles vous ne connaissez pas exactement le nom de la variable que vous recherchez, comme lorsqu'un tableau de résultats a été créé par un système de mise en file d'attente. Ceux-ci peuvent éventuellement être traités avec "ls" et son argument "pattern" qui attend une expression régulière.

La fonction "existe" pourrait être réimplémentée de cette façon

exists <-function(variablename) {
   #print(ls(env=globalenv()))
   return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}

Lors de la préparation de cette réponse, j'ai été un peu surpris de la nécessité de la spécification de l'environnement lors de l'appel de ls () à partir d'une fonction. Alors merci pour ça, stackoverflow! Il y a aussi un attribut "all.names" que j'aurais dû mettre à true mais que j'ai omis.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.