2016-11-21 3 views
-2

EDIT: Ich habe es versäumt, eine MWE mehr relevant zu meinem Anwendungsfall zu teilen.Make eval() verwenden Funktionsumgebung, anstatt globale Umgebung

Ich habe Probleme, eval() die richtige Umgebung zu verwenden.

> f = function(x) {eval.parent(parse(text = x))} 
> h = Vectorize(f, "x") 
> g = function() {a = 2; h("a")} 
> a = 1 
> h("a") 
a 
1 
> g() 
a 
1 

Oben, möchte ich g()2 zurückzukehren.

Übrigens: Ich lese Hadleys Kapitel environments und non-standard evaluation.

+0

Dies liegt an lexikalischen Scoping-Regeln in R. Verwenden Sie 'eval.parent()' anstelle von 'eval()'. Siehe diese Antwort. http://StackOverflow.com/Questions/20766649/understanding-lexical-scoping-in-r – Psidom

+0

'a' definiert außerhalb der Funktion ist' 1' so, um es von der 'g()' Funktion zu ändern, benötigen Sie: ' g = function() {a << - 2; f ("a")} '. Wie von @Psidom erwähnt, ist dies ein Problem mit dem Umfang. – Abdou

+0

@Abdou Ich möchte nicht die globale Umgebung ändern. Die Variable 'a' sollte nach dem Aufruf von 'g()' gleich '1' bleiben. – landau

Antwort

0

(Original Frage) Dadurch wird der Körper-Ausdruck aus f extrahieren und lokale bewerten zu g:

f = function(x) {eval(parse(text = x))} 
g = function() {a = 2; eval(body(f), envir = list(x="a"))} 

> g() 
[1] 2 

können auch versuchen, dieses:

> g = function() {a = 2; eval(call("f", a))} 
> g() 
[1] 2 

Zum downvoter: Es gilt höflich zu erklären, warum eine Antwort "nicht nützlich" ist. Es bleibt uns überlassen, welchen Aspekt (Korrektheit, Erwünschtheit oder ???) die Abstimmung ausgelöst haben könnte.

Nach dem Bearbeiten: Dies wird nun die gewünschte Ergebnis liefern wird und wahrscheinlich in einer weniger anstößigen Art und Weise an diejenigen, die strengen Codierung „Moral“ halten:

g = function() {a = 2; environment(h)$FUN(a)} 
g() 
#[1] 2 

Man kann die Namen herausziehen und Klassen die Einträge in der Vectorized-Funktion:

> ls.str(environment(h)) 
arg.names : chr "x" 
collisions : logi FALSE 
FUN : function (x) 
FUNV : function (x) 
SIMPLIFY : logi TRUE 
USE.NAMES : logi TRUE 
vectorize.args : chr "x" 
+0

Diese Antwort ist nicht nützlich, weil sie die Frage nicht beantwortet. OP versucht eindeutig, eine Änderung an "f" vorzunehmen, was dazu führt, dass "g" zurückgibt, was sie wollen. Das Ändern von "g" ist irrelevant. – eddi

+0

Ich dachte, das OP würde bedeuten, dass "f" unantastbar sein sollte? –

+0

So habe ich den Titel der Frage nicht gelesen, oder die Tatsache, dass OP versucht hat, 'eval' in' eval.parent' zu ändern, damit es funktioniert. – eddi

Verwandte Themen