disclaimer: this code is bad practice., and only works due to something bug-like. Never use it in a real situation. This question is about the interesting behaviour of R, nothing else than that.
After reading this question I got pretty puzzled. Apparently, ifelse can access information that should be hidden.
Say we do :
> x <- expression(dd <- 1:3)
> y <- expression(dd <- 4:6)
> z <- c(1,0)
> eval(x)
> eval(y)
>
We get no output. Logic, as both expressions are actually assignments of a vector dd. eval() is not supposed to give output then. But strangely enough, when you try the funny code
> ifelse(z==0,eval(x),eval(y))
[1] 4 2
You get output??? Somebody has an explanation for this?
It's not as simple as "R evaluates and then uses dd". Whatever order you give z, whatever condition you use, dd is always the last mentioned 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:
a closer look at the source code of ifelse shows that the line making sure this happens, is the rep()
:
> x <- expression(dd <- 1:3)
> eval(x)
> rep(eval(x),2)
[1] 1 2 3 1 2 3
Still, it doesn't solve the question...
This is not a bug
The 'output' onto the console of the result of a command is conditional. This can be determined by the function itself - for example:
> f=function(x)x;
> g=function(x)invisible(x);
> f(1)
[1] 1
> g(2)
> .Last.value
[1] 2
The value is still being returned just fine - it's just not printed on the console.
What's happening here is the eval
marks its output invisible
but rep
and ifelse
do not, and in fact effectively strip the invisible
property off their input.
It appears the invisible is a special property of the variable, and is not passed through the rep operation. It's also not passed through assignment:
> h=function(x){y=x;y;}
> f(g(1))
> h(g(1))
[1] 1
>
See ?invisible
for a little more background.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With