智能化的链接ifelse语句方式?

6

当我需要连接ifelse语句时,代码看起来像这样:

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

有没有更聪明的方法来完成这个任务?我在考虑是否创建表格然后合并它们或者类似的操作,只是为了让代码看起来更好一些?

3
使用命名向量或列表,或查看 switchfactor 函数。 - A5C1D2H2I1M1N2O1R2T1
我认为多个ifelse链更易读,如果您不缩进每个新的ifelse,而是在,NA)))之前添加换行符。 - Pekka
我建议除了最简单的ifelse语句外,其他情况都使用表格。这样更容易调试和理解。 - Hugh
3个回答

11

除了评论中的建议外,您还可以按照以下方式使用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

现在,要替换嵌套的ifelse,您可以执行以下操作:

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
@Pekka,一个小例子来测试一下会很好。你有没有想到一个? - talat
我在想像这样:x = 1:14; ifelse(x==5,'a', ifelse(x %in% c(1,4),'b', ifelse(x <= 10,'c', ifelse(x <= 12,'d', 'e')))) - Pekka
1
@Pekka,我认为这个问题会更加困难,但这同样适用于其他答案。最终,ifelse存在的原因是有道理的。如果它可以轻松地被单个其他函数替换,那么它可能根本不存在。 - talat
@docendodiscimus 好的。是的,我同意。只是想碰碰运气,看看你是否有更多关于 ifelse 的秘密知识 :)。并不是要批评你的答案,它非常好,并解决了问题! - Pekka
显示剩余2条评论

8

You can try a function like this one:

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),但我认为这样做可能不会产生非常快的性能。 - RHertel

6

另一个选项是使用 setNames

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

注意:这个例子来自@docendo discimus的帖子。

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