2010-12-06 9 views
7

Disclaimer: Dieser Code ist eine schlechte Praxis., und funktioniert nur wegen etwas Bug-like. Niemals in einer realen Situation verwenden. Diese Frage betrifft das interessante Verhalten von R, nichts anderes als das.Rs Verhalten mit ifelse und eval in Kombination

Nach dem Lesen this question wurde ich ziemlich verwirrt. Offensichtlich kann ifelse auf Informationen zugreifen, die versteckt werden sollten.

Sagen wir:

> x <- expression(dd <- 1:3)  
> y <- expression(dd <- 4:6)  
> z <- c(1,0) 

> eval(x) 
> eval(y) 
> 

Wir keine Ausgabe erhalten. Logik, da beide Ausdrücke tatsächlich Zuordnungen eines Vektors dd sind. eval() soll dann nicht ausgeben. Aber komischerweise, wenn Sie versuchen, die lustige Code

Sie erhalten Ausgabe ??? Jemand hat eine Erklärung dafür?

Es ist nicht so einfach wie "R wertet und dann verwendet dd". Egal welche Reihenfolge du z gibst, egal welche Bedingung du benutzt, dd ist immer die zuletzt erwähnte eval().

> ifelse(z==0,eval(x),eval(y)) 
> dd 
[1] 4 5 6 

> ifelse(z==1,eval(x),eval(y)) 
> dd 
[1] 4 5 6 

> z <- c(0,1) 
> ifelse(z==0,eval(x),eval(y)) 
> dd 
[1] 4 5 6 

> ifelse(z==1,eval(x),eval(y)) 
> dd 
[1] 4 5 6 

> ifelse(z==1,eval(y),eval(x)) 
> dd 
[1] 1 2 3 

EDIT:

einen genaueren Blick auf den Quellcode ifelse zeigt, dass die Linie darauf achten, dies geschieht, ist die rep():

> x <- expression(dd <- 1:3) 
> eval(x) 
> rep(eval(x),2) 
[1] 1 2 3 1 2 3 

Dennoch ist es doesn‘ t lösen die Frage ...

+1

* PROBABLY * Eval gibt unsichtbares Objekt zurück. – kohske

+0

@koshke: scheint so. str (eval (x)) gibt das Objekt an. Setzen Sie es als Antwort und ich werde akzeptieren. –

Antwort

5

Dies ist kein Fehler

Die 'Ausgabe' auf der Konsole des Ergebnisses eines Befehls ist bedingt. Dies kann durch die Funktion selbst bestimmt werden - zum Beispiel:

> f=function(x)x; 
> g=function(x)invisible(x); 
> f(1) 
[1] 1 
> g(2) 
> .Last.value 
[1] 2 

Der Wert noch zurückgegeben wird nur in Ordnung - es ist einfach nicht auf der Konsole ausgegeben.

Was geschieht hier ist die eval markiert seine Ausgabe invisible aber rep und ifelse nicht, und in der Tat effektiv abstreifen die invisible Eigenschaft von ihrem Eingang.

Es scheint, das Unsichtbare ist eine spezielle Eigenschaft der Variablen und wird nicht durch die rep-Operation übergeben. Es wird auch nicht durch Zuordnung bestanden:

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

?invisible für ein wenig mehr Hintergrund sehen.

+0

sehr richtig. Auch für die Beispiele habe ich die Funktion 'eval()' offenbar komplett falsch interpretiert. –

2

R wertet immer die beiden Alternativen zu einem ifelse Befehl aus. Sie können dies als notwendig erklären, um bereit zu sein, zu wählen, welches Element in jedem Vektor in die aufrufende Umgebung zurückkehren soll. Das Gegenteil gilt für eine if (cond) {affirm-conseq} else {neg-conseq}. Die Basis von "dd", die immer basierend auf der Auswertung des dritten ifelse-Arguments gesetzt wird, wird offenbart, wenn auf den Code für ifelse schaut.Der "Nein" -Vektorcode wird nach dem "Ja" -Vektor ausgewertet, um zu wählen, welche Elemente in dem negativen Folgevektor dem "ans" -Ausgabevektor zugewiesen werden.

+0

das war soweit ich gekommen bin. Ich habe gerade übersehen, dass eval() immer ein Objekt zurückgibt, wenn auch ein unsichtbares Objekt. –