为什么 R 的 ifelse 语句不能返回向量?

发布于 2024-08-02 12:25:57 字数 256 浏览 10 评论 0原文

我发现 R 的 ifelse 语句有时非常方便。例如:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

但我对以下行为有些困惑。

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

这是一个高于我工资等级的设计选择吗?

I've found R's ifelse statements to be pretty handy from time to time. For example:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

But I'm somewhat confused by the following behavior.

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

Is this a design choice that's above my paygrade?

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

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

发布评论

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

评论(9

十年不长 2024-08-09 12:25:57

ifelse 的文档指出:

ifelse 返回具有相同值的值
形状为 test ,其中填充有
yesyes 中选择的元素
取决于元素是否
test 的值为 TRUEFALSE

由于您传递长度为 1 的测试值,因此您将获得长度为 1 的结果。如果您传递更长的测试向量,您将获得更长的结果:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

因此 ifelse 用于测试向量的特定目的布尔值并返回相同长度的向量,填充从(向量)yesno 参数中获取的元素。

由于函数名称的原因,当您实际上只需要普通的 if () {} else {} 构造时,使用此函数是一种常见的混淆。

The documentation for ifelse states:

ifelse returns a value with the same
shape as test which is filled with
elements selected from either yes or
no depending on whether the element
of test is TRUE or FALSE.

Since you are passing test values of length 1, you are getting results of length 1. If you pass longer test vectors, you will get longer results:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

So ifelse is intended for the specific purpose of testing a vector of booleans and returning a vector of the same length, filled with elements taken from the (vector) yes and no arguments.

It is a common confusion, because of the function's name, to use this when really you want just a normal if () {} else {} construction instead.

日久见人心 2024-08-09 12:25:57

我打赌你想要一个简单的 if 语句而不是 ifelse - 在 R 中,if 不仅仅是一个控制流结构,它可以返回一个值:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4

I bet you want a simple if statement instead of ifelse - in R, if isn't just a control-flow structure, it can return a value:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4
睫毛溺水了 2024-08-09 12:25:57

请注意,如果您在 ifelse 中分配结果,则可以避免该问题:

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4

Note that you can circumvent the problem if you assign the result inside the ifelse:

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4
哎呦我呸! 2024-08-09 12:25:57

使用“if”,例如

> `if`(T,1:3,2:4)
[1] 1 2 3

use `if`, e.g.

> `if`(T,1:3,2:4)
[1] 1 2 3
老子叫无熙 2024-08-09 12:25:57

是的,我认为 ifelse() 确实是为当你有一个很大的长测试向量并且想要将每个测试向量映射到两个选项之一时而设计的。例如,我经常以这种方式为plot()设置颜色:

plot(x,y, col = ifelse(x>2,  'red', 'blue'))

如果您有一个很大的长测试向量,但想要成对的输出,您可以使用sapply()plyr 的 llply() 或其他东西,也许。

yeah, I think ifelse() is really designed for when you have a big long vector of tests and want to map each to one of two options. For example, I often do colors for plot() in this way:

plot(x,y, col = ifelse(x>2,  'red', 'blue'))

If you had a big long vector of tests but wanted pairs for outputs, you could use sapply() or plyr's llply() or something, perhaps.

那小子欠揍 2024-08-09 12:25:57

有时,用户只需要 switch 语句而不是 ifelse。在这种情况下:(

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

这是肯·威廉姆斯答案的另一个语法选项)

Sometimes the user just needs a switch statement instead of an ifelse. In that case:

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

(which is another syntax option of Ken Williams's answer)

江湖正好 2024-08-09 12:25:57

这是一种与 Cath 建议的方法类似的方法,但它可以与现有的预分配向量一起使用,

它基于使用 get() ,如下所示:

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2

Here is an approach similar to that suggested by Cath, but it can work with existing pre-assigned vectors

It is based around using the get() like so:

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2
年华零落成诗 2024-08-09 12:25:57

在您的情况下,使用 dplyr 中的 if_else 会很有帮助:if_elseifelse 更严格,并且会抛出异常您的情况出现错误:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2

In your case, using if_else from dplyr would have been helpful: if_else is more strict than ifelse, and throws an error for your case:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
素食主义者 2024-08-09 12:25:57

发现于 everydropr:

ifelse(rep(TRUE, length(c(1,2))), c(1,2),c(3,4))
#>[1] 1 2

可以复制条件结果以返回所需的长度

Found on everydropr:

ifelse(rep(TRUE, length(c(1,2))), c(1,2),c(3,4))
#>[1] 1 2

Can replicate the result of your condition to return the desired length

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