简体   繁体   English

R使用ifelse和eval组合的行为

[英]R's behaviour using ifelse and eval in combination

disclaimer: this code is bad practice. 免责声明:这段代码是不好的做法。 , and only works due to something bug-like . ,只会因为类似bug的东西而起作用 Never use it in a real situation. 切勿在真实情况下使用它。 This question is about the interesting behaviour of R, nothing else than that. 这个问题是关于R的有趣行为,没有别的。

After reading this question I got pretty puzzled. 看完这个问题后,我非常困惑。 Apparently, ifelse can access information that should be hidden. 显然,ifelse可以访问应该隐藏的信息。

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. 逻辑,因为两个表达式实际上是向量dd的赋值。 eval() is not supposed to give output then. eval()不应该给出输出。 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". 它并不像“R评估然后使用dd”那么简单。 Whatever order you give z, whatever condition you use, dd is always the last mentioned eval() . 无论你给z什么顺序,无论你使用什么条件,dd总是最后提到的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() : 仔细查看ifelse的源代码,可以看出确保发生这种情况的行是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. 这里发生的是eval标记它的输出invisiblerepifelse没有,实际上有效地剥离了它们输入的invisible属性。

It appears the invisible is a special property of the variable, and is not passed through the rep operation. 看来,invisible是变量的特殊属性,不会通过rep操作传递。 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. 看看?invisible更多的背景。

R always evaluates the two alternatives to an ifelse command. R总是评估ifelse命令的两个替代方案。 You can rationalize that as being necessary in order to be ready to choose which item in each vector to return to the calling environment. 您可以将其合理化为必要的,以便准备好选择每个向量中的哪个项目返回到调用环境。 The opposite is true of an if (cond) {affirm-conseq} else {neg-conseq} . if (cond) {affirm-conseq} else {neg-conseq} The basis of "dd" always getting set based on evaluation of the third ifelse argument is revealed when on looks at the code for ifelse . 在查看ifelse的代码时,会显示基于第三个ifelse参数的评估而设置的“dd”的基础。 The "no"-vector code gets evaluated after the "yes"-vector in order to choose which items in negative consequent vector get assigned to the "ans"-output vector. 在“是” - 向量之后评估“否” - 向量代码,以便选择负向后向量中的哪些项被分配给“ans” - 输出向量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM