Verschachtelte Funktion-Umgebung-Auswahl
Schreibe ich einige Funktionen für das erledigen wiederkehrende Aufgaben, aber ich versuche zu minimieren, wie oft ich die Daten laden. Im Grunde habe ich eine Funktion, die einige Informationen und macht eine Zeichnung. Dann habe ich eine zweite Funktion, wird die Schleife Durchlaufen, und die Ausgabe mehrerer plots zu einem .pdf. In beiden Funktionen habe ich folgende code-Zeile:
if(load.dat) load("myworkspace.RData")
wo load.dat
ist eine logische und die Daten, die ich brauchen, ist gespeichert in myworkspace.RData. Wenn ich den Aufruf der wrapper-Funktion, die durchläuft und Ausgabe mehrerer plots will ich nicht zum laden des workspace in jeder Aufruf der inneren Funktion. Ich dachte, ich könnte einfach laden Sie den Arbeitsbereich einmal in der wrapper-Funktion, dann die innere Funktion kann auf die Daten zugreifen, aber ich bekam eine Fehlermeldung, sonst.
Also mein Verständnis war, wenn eine Funktion nicht finden kann, die variable in seine lokale Umgebung (erstellt, wenn die Funktion aufgerufen wird), die Funktion Aussehen wird, das übergeordnete Umfeld für die variable.
Bin ich davon ausgegangen das übergeordnete Umgebung, die innere Funktion nennen, wäre die äußere Funktion. Offensichtlich ist dies nicht wahr:
func1 <- function(...){
print(var1)
}
func2 <- function(...){
var1 <- "hello"
func1(...)
}
> func2()
Error in print(var1) : object 'var1' not found
Nach der Lesung zahlreiche Fragen, die Sprache manual, und diese wirklich hilfreichen blog-Beitrag, ich kam mit der folgenden:
var1 <- "hello"
save(list="var1",file="test.RData")
rm(var1)
func3 <- function(...){
attach("test.RData")
func1(...)
detach("file:test.RData")
}
> func3()
[1] "hello"
Gibt es einen besseren Weg, dies zu tun? Warum nicht func1
look für Undefinierte Variablen in der lokalen Umgebung erstellt von func2
, wenn es war func2
aufgerufen func1
?
Hinweis: ich wusste nicht, wie dieser name in Frage. Wenn jemand bessere Vorschläge, ich werde es ändern, und Bearbeiten Sie diese Zeile aus.
Danke für den link. Ich werde die Arbeit durch, die an diesem Nachmittag.
Wenn Ihre Daten ist in form von dataframes, Sie könnte verwenden Paket
data.table
, und übergeben Sie Ihre Tabellen als argument zu func1
innen func3
. Dieses Paket arbeitet, von Referenz-und nicht unerwünschte Kopien Ihrer Daten.Nicht ganz sicher, warum es ist nicht zu sehen
var1
, aber beachten Sie, dass print(parent.frame()$var1)
funktioniert einwandfrei.es ist beabsichtigt, dass
func1
können nicht sehen, diese Umgebungen. Wenn Sie func1 <- function...
in der Konsole, die Sie erstellen ein Objekt vom Typ closure, die hat eine Umgebung, Immobilie, gleich R_GlobalEnv
. Dies ist, wo R-look für Symbole nicht aufgelöst, in der Beurteilung der func1
's Körper. Die Bewertung - Umgebung erstellt, die während der Ausführung func2
oder func3
ist irrelevant WRT-symbol lookup. Eine Problemumgehung ist die Verwendung parent.frame()$var1
, als Richie wies oben, aber es ist sehr hässlich.InformationsquelleAutor dayne | 2013-08-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Veranschaulichen, lexical scoping, sollten Sie Folgendes beachten:
Ersten mal erstellen Sie eine sandbox-Umgebung, nur um zu vermeiden, die ach-so-common R_GlobalEnv:
Nun setzen wir die zwei Funktionen drin:
f
, die sieht für eine variable mit dem Namenx
; undg
definiert, die eine lokalex
und fordertf
:Formsache: Eingabe-Funktion-Definitionen in der Konsole bewirkt, dass dann im umgebenden Umwelt festgelegt
R_GlobalEnv
, so dass wir manuell die Kraft Gehäuse vonf
undg
entsprechend der Umgebung, wo Sie "hingehören":Aufrufen
g
. Die lokale variablex=123
nicht gefundenf
:Nun erstellen wir eine
x
in die global Umgebung und rufen Sieg
. Die Funktionf
suchenx
zuerst in der sandbox und dann in der übergeordneten sandbox -,, die passiert werden R_GlobalEnv:Nur um zu überprüfen, dass
f
sieht fürx
zuerst in sein Gehege, wir können einex
dort und rufeng
:Fazit: symbol lookup in R folgt die Kette des umschließenden Umgebungen nicht die Auswertung frames erstellt, die während der Ausführung der verschachtelten Funktionsaufrufe.
EDIT: Nur das hinzufügen einer Verknüpfung zu diese sehr interessante Antwort von Martin Morgan auf das Thema im Zusammenhang mit der
parent.frame()
vsparent.env()
InformationsquelleAutor Ferdinand.kraft
Könnten Sie Verschlüsse:
Dann die sauberste Einstellung meiner Meinung nach: legen Sie alle Ihre Daten in einer Liste (my_data), dann geben Sie als Parameter an Ihre Funktion. Innerhalb der Funktion können Sie verwenden Sie mit(my_data, { } ), um eine zusätzliche Eingabe.
InformationsquelleAutor Karl Forner