Bagaimana cara memeriksa apakah objek (variabel) didefinisikan dalam R?


294

Saya ingin memeriksa apakah beberapa variabel didefinisikan dalam R - tanpa mendapatkan kesalahan. Bagaimana saya bisa melakukan ini?

Upaya saya (tidak berhasil):

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

Terima kasih!

Jawaban:


448

Anda ingin exists():

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

3
@ Gavin & Dirk, Anda begitu baik satu sama lain :) Satu-satunya solusi adalah Anda melempar koin (Bernoulli dengan p = 0,5 :-)) yang akan menerima terima! :-)
TMS

29
@tim jika Anda berada di dalam suatu fungsi, missing () adalah apa yang Anda inginkan.
CousinCocaine

2
Mungkin sedikit lebih rumit jika memeriksa elemen daftar: stackoverflow.com/q/7719741
TMS

5
bagaimana dengan apa yang diinginkan op - menggunakan nama variabel, bukan dalam tanda kutip?
tim

109

Lihat ?exists, untuk beberapa definisi "... didefinisikan". Misalnya

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

7
Anda menang dengan 52 detik :)
Dirk Eddelbuettel

9
@DirkEddelbuettel Nah, jika Anda akan menggunakan nama objek yang sangat panjang ;-)
Gavin Simpson

2
heh. Terjadi pada saya sepanjang waktu ketika saya menguji contoh sebelum memposting, Gavin atau Josh sudah menjawabnya.
Maiasaura

60

jika Anda berada di dalam suatu fungsi, missing () adalah apa yang Anda inginkan.

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

exchequer()
x is missing… :-(

missingNamun, hanya berfungsi untuk argumen fungsi. Anda tidak dapat melakukannya foo <- function(x) {missing(x); missing(y)}atau Anda akan mendapatkannya foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Dannid

45

Seperti yang ditunjukkan orang lain, Anda sedang mencari exists. Perlu diingat bahwa menggunakan existsdengan nama yang digunakan oleh paket dasar R akan mengembalikan true terlepas dari apakah Anda mendefinisikan variabel:

> exists("data")
[1] TRUE

Untuk menyiasati ini (seperti yang ditunjukkan oleh Bazz; lihat ?exists), gunakan inheritsargumen:

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

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

Tentu saja, jika Anda ingin mencari ruang nama paket terlampir, ini juga akan gagal:

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

Satu-satunya hal yang dapat saya pikirkan untuk mengatasi ini - untuk mencari dalam paket terlampir tetapi tidak dalam paket dasar - adalah sebagai berikut:

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

Bandingkan penggantian _object_name_dengan "data.table"( TRUE) vs. "var"( FALSE)

(tentu saja, jika Anda tidak menggunakan RStudio, saya pikir lingkungan yang terlampir secara otomatis adalah "package:stats")


2
Bermain-main, menggunakan argumen inherits = FALSEtampaknya mengisolasi hal-hal di lingkungan global. Apakah itu benar?
CJB

1
@Bazz kamu benar; Saya sudah mengedit ini menjadi jawabannya.
MichaelChirico

2
Komentar ini harus lebih tinggi, karena saya menggunakan nama variabel "data", hanya menggunakan yang ada memberi saya beberapa masalah pada awalnya.
mzm

25

Jika Anda tidak ingin menggunakan tanda kutip, Anda dapat menggunakan deparse(substitute())trik yang saya temukan di bagian contoh ?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
Anda juga dapat forceatau mengevaluasinya dalam fungsi seperti ini:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12

1

Mungkin ada situasi di mana Anda tidak tahu persis nama variabel yang Anda cari, seperti ketika array hasil telah dibuat oleh sistem antrian. Ini mungkin dapat diatasi dengan "ls" dan "pola" argumennya yang mengharapkan ekspresi reguler.

Fungsi "ada" dapat diimplementasikan kembali seperti itu

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

Sambil mempersiapkan jawaban ini, saya sedikit terkejut tentang perlunya kebutuhan spesifikasi lingkungan ketika memanggil ls () dari dalam suatu fungsi. Jadi, terima kasih untuk itu, stackoverflow! Ada juga atribut "all.names" yang seharusnya saya atur menjadi true tetapi telah dihilangkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.