【问题标题】:Smart way to chain ifelse statements?链接 ifelse 语句的聪明方法?
【发布时间】:2016-02-11 10:20:01
【问题描述】:

当我必须链接 ifelse 语句时,它看起来像:

ifelse(input=="x","x1",
       ifelse(input=="y","x2",
              ifelse(input=="z","x3",NA)))

有没有更聪明的方法来做到这一点?我正在考虑创建表然后合并或类似的东西只是为了让代码看起来更好?

【问题讨论】:

  • 使用命名向量或列表,或查看switch 或factor。
  • 我发现多个 ifelse 链更具可读性如果您不缩进每个新的 ifelse,而是在 ,NA))) 之前添加换行符。
  • 除了最简单的ifelse 语句之外,我建议使用表。使调试和理解更容易。

标签: r if-statement


【解决方案1】:

除了 cmets 中的建议外,您还可以通过以下方式使用match。

创建样本数据:

set.seed(1)
vals_in <- c("x", "y", "z")   # unique values in your input vector
vec_in <- sample(vals_in, 10, replace = TRUE)  # sample from vals_in to create input
vals_out <-  c("x1", "x2", "x3")  # values to replace

现在,要替换嵌套的 ifelses,您可以这样做:

vec_out <- vals_out[match(vec_in, vals_in)]

结果是

vec_out
# [1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"

两种方法的小比较:

set.seed(1)
vals_in <- letters
vec_in <- sample(vals_in, 1e7, replace = TRUE)
vals_out <-  LETTERS

system.time(vals_out[match(vec_in, vals_in)])
       User      System verstrichen 
      0.378       0.020       0.398 
system.time(unname(setNames(vals_out, vals_in)[vec_in]))
       User      System verstrichen 
      1.020       0.062       1.084 

【讨论】:

  • 这很酷。但是有什么建议如何处理其他类型的条件,比如不等式?
  • @Pekka,一个小例子可以很好地测试它。你有一个想法吗?
  • 嗯,我在想这样的事情:x = 1:14; ifelse(x==5,'a', ifelse(x %in% c(1,4),'b', ifelse(x &lt;= 10,'c', ifelse(x &lt;= 12,'d', 'e'))))
  • 好比较,加一。
  • @Pekka,我认为这样的问题会更加困难,但这同样适用于这里的所有其他答案。最后,ifelse 的存在是有原因的。如果它很容易被单个其他功能替换,它可能一开始就不会存在
【解决方案2】:

你可以试试这样的功能:

choice <- function(input) {
  switch(input,
         "x"="x1",
         "y"="x2",
         "z"="x3",
         NA)
}
#> choice("x")
#[1] "x1"
#> choice("z")
#[1] "x3"
#> choice("other")
#[1] NA

【讨论】:

  • @docendodiscimus 可以将此函数包装到 sapply() 中以处理输入向量,如下所示:sapply(my_vector, choice),但我认为这不会产生非常快的性能。
【解决方案3】:

另一种选择是使用setNames

unname(setNames(vals_out, vals_in)[vec_in])
#[1] "x1" "x2" "x2" "x3" "x1" "x3" "x3" "x2" "x2" "x1"

注意:以@docendo discimus 帖子为例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    相关资源
    最近更新 更多