结合使用 ifelse 和 eval 的 R 行为

发布于 2024-10-06 09:44:58 字数 1280 浏览 0 评论 0原文

免责声明:此代码是不好的做法。,并且仅在某些类似错误的情况下才有效切勿在真实情况下使用它。这个问题是关于 R 的有趣行为,仅此而已。

阅读这个问题我很困惑。显然,ifelse 可以访问应该隐藏的信息。

假设我们这样做:

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

> eval(x)
> eval(y)
>

我们没有得到任何输出。逻辑,因为两个表达式实际上都是向量 dd 的赋值。 eval() 不应该给出输出。但奇怪的是,当你尝试有趣的代码时,

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

你会得到输出???有人对此有解释吗?

它并不像“R 评估然后使用 dd”那么简单。无论您给 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

编辑:

仔细查看 ifelse 的源代码表明,确保发生这种情况的行是 rep()

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

不过,它并没有解决问题......

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

停滞 2024-10-13 09:44:58

这不是一个错误

命令结果到控制台的“输出”是有条件的。这可以由函数本身确定 - 例如:

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

该值仍然正常返回 - 它只是没有打印在控制台上。

这里发生的情况是,eval 将其输出标记为invisible,但 repifelse 没有,并且实际上有效地剥离了他们的输入中的invisible属性。

看起来不可见是变量的特殊属性,并且不通过代表操作传递。它也不是通过赋值传递的:

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

请参阅 ?invisible 了解更多背景信息。

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.

夜深人未静 2024-10-13 09:44:58

R 始终评估 ifelse 命令的两个替代方案。您可以将其合理化为必要的,以便准备好选择每个向量中的哪个项目返回到调用环境。 if (cond) {affirm-conseq} else {neg-conseq} 的情况正好相反。当查看 ifelse 的代码时,就会发现“dd”的基础总是根据第三个 ifelse 参数的评估来设置。在“yes”向量之后评估“no”向量代码,以便选择将负后续向量中的哪些项目分配给“ans”输出向量。

R always evaluates the two alternatives to an ifelse command. 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}. 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. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文