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.