Odpowiedzi:
Chcesz exists()
:
R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R>
Zobacz ?exists
definicję „... jest zdefiniowane”. Na przykład
> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE
jeśli jesteś w funkcji, brak () jest tym, czego chcesz.
exchequer = function(x) {
if(missing(x)){
message("x is missing… :-(")
}
}
exchequer()
x is missing… :-(
missing
działa jednak tylko dla argumentów funkcji. Nie możesz tego zrobić foo <- function(x) {missing(x); missing(y)}
albo dostaniesz foo(1)
> Error in missing(y) : 'missing' can only be used for arguments
.
Jak zauważyli inni, szukasz exists
. Należy pamiętać, że użycie exists
z nazwami używanymi przez pakiety podstawowe R zwróci wartość true niezależnie od tego, czy zmienna została zdefiniowana:
> exists("data")
[1] TRUE
Aby obejść ten problem (jak wskazał Bazz; patrz ?exists
), użyj inherits
argumentu:
> exists("data", inherits = FALSE)
[1] FALSE
foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE
Oczywiście, jeśli chcesz przeszukiwać przestrzenie nazw dołączonych pakietów, byłoby to również niewystarczające:
> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE
Jedyne, co mogę wymyślić, aby to obejść - szukać w załączonych pakietach, ale nie w pakietach podstawowych - to:
any(sapply(1:(which(search() == "tools:rstudio") - 1L),
function(pp) exists(_object_name_, where = pp, inherits = FALSE)))
Porównaj wymianie _object_name_
z "data.table"
( TRUE
) vs "var"
( FALSE
)
(oczywiście, jeśli nie korzystasz z RStudio, myślę, że pierwszym automatycznie podłączonym środowiskiem jest "package:stats"
)
inherits = FALSE
wydaje się izolować rzeczy w globalnym środowisku. Czy to brzmi dobrze?
Jeśli nie chcesz używać cudzysłowów, możesz użyć deparse(substitute())
sztuczki, którą znalazłem w przykładowej sekcji ?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
force
lub ocenić to w funkcji takiej jak ta:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
Mogą wystąpić sytuacje, w których nie znasz dokładnie nazwy szukanej zmiennej, na przykład gdy tablica wyników została utworzona przez system kolejkowania. Można je rozwiązać za pomocą „ls” i jego argumentu „wzorzec”, który oczekuje wyrażenia regularnego.
Funkcję „istnieje” można ponownie zaimplementować w ten sposób jako
exists <-function(variablename) {
#print(ls(env=globalenv()))
return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}
Przygotowując tę odpowiedź, byłem nieco zaskoczony potrzebą specyfikacji środowiska podczas wywoływania ls () z funkcji. Dziękuję za to, przepełnienie stosu! Istnieje również atrybut „all.names”, który powinienem był ustawić na true, ale go pominąłem.