[英]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
标记它的输出invisible
但rep
和ifelse
没有,实际上有效地剥离了它们输入的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.