Como verificar se o objeto (variável) está definido no R?


294

Gostaria de verificar se alguma variável está definida no R - sem obter um erro. Como posso fazer isso?

Minhas tentativas (sem êxito):

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

Obrigado!

Respostas:


448

Você quer exists():

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

3
@ Gavin & Dirk, vocês são tão legais um com o outro :) A única solução é você jogar a moeda (Bernoulli com p = 0,5 :-)) que receberá a aceitação! :-)
TMS

29
@tim se você estiver dentro de uma função, falta () é o que você deseja.
CousinCocaine

2
Pode ficar um pouco mais complicado se procurar por elementos da lista: stackoverflow.com/q/7719741
TMS

5
e o que o op queria - usando o nome da variável, não entre aspas?
tim

109

Veja ?exists, para alguma definição de "... está definido". Por exemplo

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

7
Você ganha por 52 segundos :)
Dirk Eddelbuettel

9
@DirkEddelbuettel Bem, se você vai usar nomes de objetos ridiculamente longos ;-)
Gavin Simpson

2
heh Acontece comigo o tempo todo, quando estou testando exemplos antes de postar, Gavin ou Josh já responderam.
Maiasaura

60

se você estiver dentro de uma função, falta () é o que você deseja.

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

exchequer()
x is missing… :-(

missingsó funciona para argumentos de função, no entanto. Você não pode fazer foo <- function(x) {missing(x); missing(y)}ou vai conseguir foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Dannid 11/02/19

45

Como outros já apontaram, você está procurando exists. Lembre-se de que o uso existscom nomes usados ​​pelos pacotes base de R retornará true, independentemente de você ter definido a variável:

> exists("data")
[1] TRUE

Para contornar isso (como apontado por Bazz; consulte ?exists), use o inheritsargumento:

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

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

Obviamente, se você quisesse pesquisar os espaços de nomes dos pacotes anexados, isso também seria insuficiente:

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

A única coisa que posso pensar para contornar isso - pesquisar nos pacotes anexados, mas não nos pacotes base - é o seguinte:

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

Compare a substituição _object_name_por "data.table"( TRUE) vs. "var"( FALSE)

(é claro, se você não está no RStudio, acho que o primeiro ambiente conectado automaticamente é "package:stats")


2
Brincando, usar argumentos inherits = FALSEparece isolar as coisas no ambiente global. Isso soa certo?
CJB

1
@Azz você está correto; Eu editei isso na resposta.
21416 MichaelChirico

2
Esse comentário deve ser mais alto, já que eu uso o nome da variável "data", apenas o uso de exist me deu alguns problemas inicialmente.
Mzm

25

Se você não quiser usar aspas, use o deparse(substitute())truque que encontrei na seção de exemplo 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
você também pode forceou avaliá-lo na função da seguinte maneira:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12 4/17

1

Pode haver situações em que você não saiba exatamente o nome da variável que está procurando, como quando uma matriz de resultados foi criada por um sistema de enfileiramento. Eles podem ser endereçados com "ls" e seu argumento "padrão" que espera uma expressão regular.

A função "existe" pode ser reimplementada dessa maneira, como

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

Ao preparar esta resposta, fiquei um pouco surpreso com a necessidade da especificação do ambiente ao invocar ls () de dentro de uma função. Então, obrigado por isso, stackoverflow! Há também um atributo "all.names" que eu deveria ter definido como verdadeiro, mas omitido.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.