如何在R中正确使用ifelse()?

xam8gpfp  于 2023-02-06  发布在  其他
关注(0)|答案(3)|浏览(155)

给定以下代码:

a <- 3
colors <-  ifelse(a == 3,
c("#004B93", "#389DC3", "#6DBE99"),
ifelse(a == 2, c("#004B93", "#389DC3"), c("#000000", "#000000", "#000000")))

我的期望是得到像

> colors 
[1] "#004B93" "#389DC3" "#6DBE99"

但我得到的是

> colors
[1] "#004B93"

我哪里做错了?

pb3skfrl

pb3skfrl1#

你也可以使用if else语句来检查R中的条件。
对于这一点,你可以做同样的逻辑,因为我为你检查。

a <- 3
colors <- if(a == 3) {
c("#004B93", "#389DC3", "#6DBE99")
} else if (a == 2) {
c("#004B93", "#389DC3")
} else {
c("#000000", "#000000", "#000000")
}

print(colors)

输出结果:

[1] "#004B93" "#389DC3" "#6DBE99"
mwkjh3gx

mwkjh3gx2#

我是这样写的:

possible_colors = list(
    c("#000000", "#000000", "#000000"),
    c("#004B93", "#389DC3"),
    c("#004B93", "#389DC3", "#6DBE99")
)

colors = if (a < 1L || a > 3L) list[[1L]] else list[[a]]

这里假设a只有整数值。如果不是这样,请相应地调整if的条件。
如果您知道a永远不会是除1、2或3之外的任何值,则可以完全省略if并直接写入colors = possible_colors[[a]]

kzmpq1sx

kzmpq1sx3#

ifelse是 * 通常 * 最好避免的命令。
为什么?因为

ifelse(TRUE, 1:3, 4:6)

返回1而不是1:3
实际上,ifelse希望输出与测试的长度相同,TRUE上面是长度为1的向量,而候选输出1:3的长度为3,但是ifelse并没有发出任何警告,它只是 * 剪切了 * 向量1:3
这背后是有道理的,下面的例子可以解释这一点:

ifelse(c(TRUE, FALSE, TRUE), yes = 1:3, no = 4:6)
[1] 1 5 3

真值取自yes参数,假值取自no参数。如果您真的想要这种复杂的行为,ifelse可以非常强大,但这很少是您想要的。
好消息是R是一种函数式语言,因此任何东西都是函数,包括if/else结构。

ret <- ifelse(TRUE, 1:3, 4:6)

这样重写:

ret <- if(TRUE) 1:3 else 4:6

并且ret1:3
你需要嵌套条件吗?没问题。

a <- 1 
ret <- if(a == 1) 1:3 else (if(a == 2) 4:6 else 7:9)

上面这行强调了函数方法,我用括号中的表达式替换了4:6,但它可以缩短为:

ret <- if(a == 1) 1:3 else if(a == 2) 4:6 else 7:9

但是,请注意,对于此类任务,有一个专用的R函数:switch .

ret <- switch(a, 1:3, 4:6, 7:9)

a之后计数,根据a的值选择第一、第二等自变量,因此:

a <- 2
switch(a, 1:3, 4:6, 7:9)
# 4:6

至于你的情况:

a <- 3
switch(a, 
       c("#000000", "#000000", "#000000"),
       c("#004B93", "#389DC3"), 
       c("#004B93", "#389DC3", "#6DBE99"))

# [1] "#004B93" "#389DC3" "#6DBE99"

相关问题