R中是否存在三元运算符?


175

正如问题所问,R中是否存在类似于C的三元运算符的控制序列?如果是这样,您如何使用它?谢谢!


1
您是否需要比强大的功能ifelse,或者只是更紧凑的形式?
卡尔·威索夫特

@CarlWitthoft大多数形式更紧凑;只是一种节省写作的方法if (x>1) y=2 else y=3y=曾经的写作对此有一定的吸引力。
eykanal 2012年

Answers:


302

作为if函数R并返回最新评估,if-else等效于?:

> a <- 1
> x <- if(a==1) 1 else 2
> x
[1] 1
> x <- if(a==2) 1 else 2
> x
[1] 2

R的功效是矢量化。三元运算符的向量化为ifelse

> a <- c(1, 2, 1)
> x <- ifelse(a==1, 1, 2)
> x
[1] 1 2 1
> x <- ifelse(a==2, 1, 2)
> x
[1] 2 1 2

只是在开玩笑,您可以定义c-style ?:

`?` <- function(x, y)
    eval(
      sapply(
        strsplit(
          deparse(substitute(y)), 
          ":"
      ), 
      function(e) parse(text = e)
    )[[2 - as.logical(x)]])

在这里,您无需注意括号:

> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4
> TRUE ? x*2 : 0
[1] 2
> FALSE ? x*2 : 0
[1] 0

但是你需要用括号括起来:(

> y <- 1 ? 2*3 : 4
[1] 6
> y
[1] 1
> y <- (1 ? 2*3 : 4)
> y
[1] 6

最后,您可以使用c做非常相似的方式:

`?` <- function(x, y) {
  xs <- as.list(substitute(x))
  if (xs[[1]] == as.name("<-")) x <- eval(xs[[3]])
  r <- eval(sapply(strsplit(deparse(substitute(y)), ":"), function(e) parse(text = e))[[2 - as.logical(x)]])
  if (xs[[1]] == as.name("<-")) {
    xs[[3]] <- r
        eval.parent(as.call(xs))
  } else {
    r
  }
}       

您可以删除括号:

> y <- 1 ? 2*3 : 4
> y
[1] 6
> y <- 0 ? 2*3 : 4
> y
[1] 4
> 1 ? 2*3 : 4
[1] 6
> 0 ? 2*3 : 4
[1] 4

这些不是日常使用,但可能对学习R语言的某些内部知识很有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.