R using ifelse and eval in combination

disclaimer: this code is bad practice. and only works because of something like . Never use it in a real situation. This question concerns the interesting behavior of R, nothing like this.

After reading this question, I was puzzled. Apparently ifelse can access information that should be hidden.

Let's say we do:

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

We do not get a way out. Logic, since both expressions are actually a dd vector. eval () should not give a result then. But oddly enough, when you try funny code

 > ifelse(z==0,eval(x),eval(y)) [1] 4 2 

Do you get a way out ??? Does anyone have an explanation?

It is not as simple as "R evaluates and then uses dd." Whatever order you specify, 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 ifelse source code reveals that the line, making sure this happens, is rep() :

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

However, this does not solve the issue ...

+7
eval r if-statement
source share
2 answers

It's not a mistake

"Exit" to the console result of the command 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 still returns just fine - it just doesn't print to the console.

What happens here, eval notes its invisible output, but rep and ifelse does not, and effectively effectively disconnects the invisible property from their input.

It seems that the invisible is a special property of the variable and is not passed through the rep operation. He also did not go through the appointment:

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

See ?invisible more details.

+5
source share

R always evaluates two alternatives to the ifelse command. You can rationalize this as necessary to be ready to choose which element in each vector will return to the calling environment. The opposite applies to if (cond) {affirm-conseq} else {neg-conseq} . The "dd" framework, which always gets a set based on evaluating the third ifelse argument, expands when viewing code for ifelse . The no -vector code is evaluated after the yes -vector to select which elements in the negative subsequent vector will be assigned to the ans vector.

+2
source share

All Articles