Nesnenin (değişken) R'de tanımlanıp tanımlanmadığı nasıl kontrol edilir?


294

Bir hata almadan bazı R - tanımlanmış olup olmadığını kontrol etmek istiyorum. Bunu nasıl yapabilirim?

Girişimlerim (başarılı değil):

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

Teşekkürler!

Yanıtlar:


449

İstediğiniz exists():

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

3
@Gavin & Dirk, birbirinize karşı çok iyisiniz :) Tek çözüm kabul edeceğiniz parayı (p = 0.5 :-) ile Bernoulli) atmanızdır! :-)
TMS

29
@tim Bir işlevin içindeyseniz, eksik () istediğiniz şeydir.
CousinCocaine

2
Liste öğelerini kontrol ediyorsanız biraz daha zor olabilir: stackoverflow.com/q/7719741
TMS

5
op'un ne istediğine bakalım - değişken adını kullanarak, tırnak işaretleri arasında değil?
tim

109

?exists"... Tanımlandı" nın bazı tanımları için bakınız . Örneğin

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

7
52 saniye kazanırsınız :)
Dirk Eddelbuettel

9
@DirkEddelbuettel Gülünç derecede uzun nesne isimleri kullanacaksanız ;-)
Gavin Simpson

2
heh. Göndermeden önce örnekleri test ettiğimde her zaman bana oluyor, Gavin veya Josh zaten cevapladı.
Maiasaura

60

bir işlevin içindeyseniz, eksik () istediğiniz şeydir.

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

exchequer()
x is missing… :-(

missingancak yalnızca işlev bağımsız değişkenleri için kullanılabilir. Yapamazsın foo <- function(x) {missing(x); missing(y)}ya da alacaksın foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Dannid

46

Diğerlerinin işaret ettiği gibi, siz arıyoruz exists. Kullanarak unutmayın existsR'ın baz paketleri tarafından kullanılan adlarla bakılmaksızın tanımlı değişkenlere da geçerlidir döndürür:

> exists("data")
[1] TRUE

Bu sorunu aşmak için (Bazz'ın işaret ettiği gibi; bkz. ?exists), Şu inheritsargümanı kullanın :

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

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

Tabii ki, ekli paketlerin ad alanlarını aramak isterseniz, bu da kısa olur:

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

Bunu ele almayı düşünebildiğim tek şey - ekli paketlerde arama yapmak, ancak temel paketlerde değil - aşağıdakilerdir:

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

( ) Ve ( _object_name_ile değiştirmeyi karşılaştırın"data.table"TRUE"var"FALSE )

(elbette, RStudio'da değilseniz, ilk otomatik olarak bağlanan ortamın olduğunu düşünüyorum "package:stats")


2
Etrafta oynamak, argüman kullanmak inherits = FALSEküresel ortamdaki şeyleri izole ediyor gibi görünüyor. Kulağa doğru geliyor mu?
CJB

1
@Baz haklısın; Bunu cevabın içinde düzenledim.
MichaelChirico

2
Değişken adı "veri" kullandığım için bu yorum daha yüksek olmalıdır, sadece var olmak başlangıçta bana biraz sorun verdi.
mzm

25

Tırnak işareti kullanmak istemiyorsanız deparse(substitute()), aşağıdaki örnek bölümde bulduğum hileyi kullanabilirsiniz ?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
aşağıdakileri de yapabilirsiniz forceya böyle işlevde değerlendirmek:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12

1

Kuyruk sistemi tarafından bir dizi sonuç oluşturulduğunda olduğu gibi, aradığınız değişkenin adını tam olarak bilmediğiniz durumlar olabilir. Bunlar muhtemelen "ls" ve normal bir ifade bekliyor argümanı "desen" ile ele alınabilir.

"Varoluş" işlevi şu şekilde yeniden uygulanabilir:

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

Bu cevabı hazırlarken, bir fonksiyon içinden ls () çağırırken ortamın spesifikasyonunun gerekliliği konusunda biraz şaşırdım . Bunun için teşekkürler, yığın akışı! Ayrıca true olarak ayarlamam gereken ancak atlamam gereken bir "all.names" özniteliği de vardır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.