¿Cómo verificar si el objeto (variable) está definido en R?


294

Me gustaría verificar si alguna variable está definida en R, sin obtener un error. ¿Cómo puedo hacer esto?

Mis intentos (no exitosos):

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

¡Gracias!

Respuestas:


448

Tu quieres exists():

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

3
@Gavin y Dirk, son muy amables el uno con el otro :) ¡La única solución es tirar la moneda (Bernoulli con p = 0.5 :-)) que recibirá la aceptación! :-)
TMS

29
@tim si está dentro de una función, missing () es lo que desea.
CousinCocaine

2
Puede ser un poco más complicado si busca elementos de la lista: stackoverflow.com/q/7719741
TMS

55
¿Qué pasa con lo que el operador quería: usar el nombre de la variable, no entre comillas?
tim

109

Ver ?exists, para alguna definición de "... se define". P.ej

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

77
Ganas

99
@DirkEddelbuettel Bueno, si vas a usar nombres de objetos ridículamente largos ;-)
Gavin Simpson

2
je Me sucede todo el tiempo cuando estoy probando ejemplos antes de publicar, Gavin o Josh ya lo han respondido.
Maiasaura

60

si está dentro de una función, falta () es lo que desea.

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

exchequer()
x is missing… :-(

missingSin embargo, solo funciona para argumentos de función. No puedes hacer foo <- function(x) {missing(x); missing(y)}o obtendrás foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Dannid

45

Como otros han señalado, estás buscando exists. Tenga en cuenta que usar existscon los nombres utilizados por los paquetes base de R devolvería verdadero independientemente de si definió la variable:

> exists("data")
[1] TRUE

Para evitar esto (como señaló Bazz; ver ?exists), use el inheritsargumento:

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

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

Por supuesto, si desea buscar los espacios de nombres de los paquetes adjuntos, esto también se quedaría corto:

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

Lo único en lo que puedo pensar para evitar esto, para buscar en paquetes adjuntos pero no en paquetes básicos, es lo siguiente:

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

Comparar reemplazo _object_name_ con "data.table"( TRUE) vs. "var"( FALSE)

(por supuesto, si no estás en RStudio, creo que el primer entorno conectado automáticamente es "package:stats")


2
Jugar, usar argumentos inherits = FALSEparece aislar las cosas en el entorno global. ¿Eso suena bien?
CJB

1
@Bazz tienes razón; He editado esto en la respuesta.
MichaelChirico

2
Este comentario debería estar más arriba, ya que uso el nombre de variable "data", solo usar exist me dio algunos problemas inicialmente.
mzm

25

Si no desea usar comillas, puede usar el deparse(substitute())truco que encontré en la sección de ejemplos 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
también puede forceo evaluarlo en la función como esta:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12

1

Puede haber situaciones en las que no sepa exactamente el nombre de la variable que está buscando, como cuando un sistema de colas ha creado una matriz de resultados. Posiblemente se puedan abordar con "ls" y su argumento "patrón" que espera una expresión regular.

La función "existe" podría reimplementarse de esa manera

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

Mientras preparaba esta respuesta, me sorprendió un poco la necesidad de la especificación del entorno al invocar ls () desde una función. Entonces, gracias por eso, stackoverflow! También hay un atributo "all.names" que debería haber establecido en verdadero pero que he omitido.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.