在R中替代多个ifelse的方法

3

我厌倦了在R中使用多个ifelse语句。我知道有一个名为switch的函数,但无法弄清如何在以下示例中使用它。

set.seed(12345)
Y <- runif(n=100, min=0, max=50)

ifelse(
    test = Y < 5
  , yes  = "A"
  , no   =  ifelse(
         test = Y < 10
       , yes  = "B"
       , no = "C"
       )
    )

输出:

  [1] "C" "C" "C" "C" "C" "B" "C" "C" "C" "C" "A" "B" "C" "A" "C" "C" "C" "C"
 [19] "B" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "C" "A" "B" "C" "C" "C"
 [37] "C" "C" "C" "B" "C" "C" "C" "C" "C" "C" "A" "A" "A" "C" "C" "C" "C" "C"
 [55] "C" "C" "C" "A" "C" "C" "C" "C" "C" "C" "C" "C" "C" "B" "C" "C" "C" "C"
 [73] "C" "C" "A" "C" "C" "C" "C" "B" "C" "C" "A" "A" "B" "C" "C" "C" "C" "A"
 [91] "C" "C" "A" "C" "C" "C" "C" "C" "A" "C"

编辑

如果我有以下代码,那么是否有比 ifelse 语句更好的替代方案?

set.seed(12345)
Y <- runif(n=100, min=0, max=50)

ifelse(
    test = Y < 5
  , yes  = -5
  , no   =  ifelse(
         test = Y < 10
       , yes  = 0
       , no = 5
       )
    )

2
你可以查看 ?cut - Dason
1
也许你感到疲倦部分是因为打出这些参数名 test, yes, no。实际上,它们并不必要,可以使用 ifelse(Y<5,"A",ifelse(Y<10, "B","C")) 这样的语句替代。 - flodel
@flodel:是的,你说得对!!! 但这是很好拥有的。 - MYaseen208
2
关于cut的概念,还可以参考?findInterval。如果符合您的需求,它可能会更快,因为它产生的输出比cut不太“整洁”。LETTERS[findInterval(Y, c(-Inf, 5, 10, Inf))] - alexis_laz
@alexis_lax:在这里使用findInterval(Y,c(5,10))就足够了(不需要无穷大),尽管需要一个+1来将它们转换为正确的索引进入LETTERS - user295691
2个回答

8

switch并不适合处理这种情况,使用cut更好:

cut(Y,c(-Inf,5,10,Inf),labels=LETTERS[1:3],right=FALSE)
  [1] C C C C C B C C C C A B C A C C C C B C C C C C C C C C C C C A B C C C C
 [38] C C B C C C C C C A A A C C C C C C C C A C C C C C C C C C B C C C C C C
 [75] A C C C C B C C A A B C C C C A C C A C C C C C A C
Levels: A B C

谢谢@James的回答。如果我需要从cut中获取数字值而不是字母。 - MYaseen208
@MYaseen208 我不确定你想要什么,但是参数 labels=FALSE 将会给出底层整数代码而不是因子。 - James
@MYaseen208 您可以通过 cut 的输出来对选择向量进行子集化,即 c(-5,0,5)[cut(...)],或者使用 @alexis_laz 建议的 findInterval 方法。 - James
@jbest 我不确定你的意思,而且我认为你正在偏离原始问题。你能否提出一个单独的问题并提供更多细节? - James

1
这是一种基于逻辑和数学运算的方法(针对您的编辑):
5 * ((Y >= 10) - (Y < 5))

 [1]  5  5  5  5  5  0  5  5  5  5 -5  0  5 -5  5  5  5  5  0  5  5  5
[23]  5  5  5  5  5  5  5  5  5 -5  0  5  5  5  5  5  5  0  5  5  5  5
[45]  5  5 -5 -5 -5  5  5  5  5  5  5  5  5 -5  5  5  5  5  5  5  5  5
[67]  5  0  5  5  5  5  5  5 -5  5  5  5  5  0  5  5 -5 -5  0  5  5  5
[89]  5 -5  5  5 -5  5  5  5  5  5 -5  5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接