Was ist der Unterschied zwischen parent.frame () und parent.env () in R; Wie unterscheiden sie sich im Aufruf durch Referenz?

82

Es wäre hilfreich, wenn jemand dies anhand eines einfachen Beispiels veranschaulichen könnte.

Auch wo wäre es sinnvoll, parent.frame()anstelle von parent.env()und umgekehrt zu verwenden.

Suncoolsu
quelle

Antworten:

97

parent.envist die Umgebung, in der ein Abschluss (z. B. eine Funktion) definiert ist. parent.frameist die Umgebung, aus der die Schließung aufgerufen wurde.

f = function() 
     c(f=environment(), defined_in=parent.env(environment()),  
       called_from=parent.frame())
g = function() 
     c(g=environment(), f())

und dann

> g()
$g
<environment: 0x14060e8>

$f
<environment: 0x1405f28>

$defined_in
<environment: R_GlobalEnv>

$called_from
<environment: 0x14060e8>

Ich bin mir nicht sicher, wann ein Sterblicher sie jemals wirklich benutzen möchte, aber die Konzepte sind nützlich, um den lexikalischen Umfang hier zu verstehen

> f = function() x
> g = function() { x = 2; f() }
> h = function() { x = 3; function() x }
> x = 1
> f()
[1] 1
> g()
[1] 1
> h()()
[1] 3

oder im rätselhaften Beispiel 'Bankkonto' in der Einführung zu R. Der erste Absatz des Abschnitts Details von ?parent.framekönnte die Dinge klarstellen.

Umgebungen sind in R allgegenwärtig, z. B. besteht der search()Pfad aus (ungefähr) Umgebungen, die in einer Geschwister-> Elternbeziehung miteinander verkettet sind. Manchmal wird versucht, die Symbolsuche env = new.env(parent=emptyenv())zu umgehen - normalerweise wird env[["x"]]zuerst nach envund dann nach envdem Elternteil gesucht, wenn es nicht gefunden wird. Ebenso <<-sucht die Zuordnung ab dem parent.env. Die relativ neue Referenzklassenimplementierung in R basiert auf diesen Ideen, um eine instanzspezifische Umgebung zu definieren, in der Symbole (Instanzfelder und Methoden) gefunden werden können.

Martin Morgan
quelle