Antworten:
Sie wollen exists():
R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R>
Siehe ?existsfür eine Definition von "... ist definiert". Z.B
> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE
Wenn Sie sich in einer Funktion befinden, möchten Sie (() nicht ().
exchequer = function(x) {
if(missing(x)){
message("x is missing… :-(")
}
}
exchequer()
x is missing… :-(
missingfunktioniert jedoch nur für Funktionsargumente. Sie können nicht tun foo <- function(x) {missing(x); missing(y)}oder Sie werden bekommen foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Wie andere betont haben, suchen Sie exists. Beachten Sie, dass die Verwendung existsmit Namen, die von Rs Basispaketen verwendet werden, true zurückgibt, unabhängig davon, ob Sie die Variable definiert haben:
> exists("data")
[1] TRUE
?existsVerwenden Sie das folgende inheritsArgument , um dies zu umgehen (wie von Bazz hervorgehoben; siehe ).
> exists("data", inherits = FALSE)
[1] FALSE
foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE
Wenn Sie die Namensräume angehängter Pakete durchsuchen möchten, ist dies natürlich auch nicht ausreichend:
> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE
Das einzige, was ich mir vorstellen kann, um dies zu umgehen - in angehängten Paketen zu suchen, aber nicht in Basispaketen - ist das Folgende:
any(sapply(1:(which(search() == "tools:rstudio") - 1L),
function(pp) exists(_object_name_, where = pp, inherits = FALSE)))
Vergleiche Ersetzen _object_name_mit "data.table"( TRUE) vs. "var"( FALSE)
(Wenn Sie nicht auf RStudio sind, ist die erste automatisch angehängte Umgebung natürlich "package:stats")
inherits = FALSEscheint die Dinge in der globalen Umgebung zu isolieren. Klingt das richtig?
Wenn Sie keine Anführungszeichen verwenden möchten, können Sie einen deparse(substitute())Trick verwenden, den ich im Beispielabschnitt von ?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
forceoder in der Funktion wie is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
Es kann Situationen geben, in denen Sie den Namen der gesuchten Variablen nicht genau kennen, z. B. wenn ein Warteschlangensystem eine Reihe von Ergebnissen erstellt hat. Diese können möglicherweise mit "ls" und seinem Argument "pattern" angesprochen werden, das einen regulären Ausdruck erwartet.
Die Funktion "existiert" könnte auf diese Weise wie folgt neu implementiert werden
exists <-function(variablename) {
#print(ls(env=globalenv()))
return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}
Während ich diese Antwort vorbereitete, war ich ein wenig überrascht über die Notwendigkeit, die Spezifikation der Umgebung zu benötigen, wenn ls () innerhalb einer Funktion aufgerufen wird . Also, danke dafür, Stackoverflow! Es gibt auch ein "all.names" -Attribut, das ich auf true hätte setzen sollen, aber weggelassen habe.