valido usar ternario operador ejemplos r operators

usar - ¿Existe el operador ternario en R?



operador ternario python (7)

¿Solo como una broma, puedes redefinir el ? operador para (casi) trabajar como el operador ternario (ESTA ES UNA MALA IDEA):

`?` <- function(x, y) { y <-substitute(y); if(x) eval(y[[2]], parent.frame()) else eval(y[[3]], parent.frame()) } x <- 1:3 length(x) ? (x*2) : 0 x <- numeric(0) length(x) ? (x*2) : 0 for(i in 1:5) cat(i, (i %% 2) ? "Odd/n" : "Even/n")

... Pero debe poner las expresiones entre paréntesis porque la precedencia predeterminada no es como en C.

Solo recuerda restaurar la antigua función de ayuda cuando termines de jugar:

rm(`?`)

Como pregunta, ¿hay una secuencia de control en R similar al operador ternario de C? Si es así, cómo lo usas? ¡Gracias!


Como if función en R y devuelve la última evaluación, if-else es equivalente a ?: .

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

El poder de R es la vectorización. La vectorización del operador ternario es 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

Es broma, ¿puedes definir el estilo c ?:

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

aquí, no necesita preocuparse por los corchetes:

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

pero necesitas paréntesis para la asignación :(

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

Finalmente, puedes hacer una manera muy similar con 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 } }

Puedes deshacerte de los paréntesis:

> 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

Estos no son para uso diario, pero tal vez sean buenos para aprender algunos aspectos internos del lenguaje R.


Como todos los demás dijeron, use ifelse , pero puede definir operadores para que casi tenga la sintaxis del operador ternario.

`%?%` <- function(x, y) list(x = x, y = y) `%:%` <- function(xy, z) if(xy$x) xy$y else z TRUE %?% rnorm(5) %:% month.abb ## [1] 0.05363141 -0.42434567 -0.20000319 1.31049766 -0.31761248 FALSE %?% rnorm(5) %:% month.abb ## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" # or, more generally condition %?% value1 %:% value2

Realmente funciona si defines los operadores sin los signos % , entonces podrías tener

`?` <- function(x, y) if(x) y[[1]] else y[[2]] `:` <- function(y, z) list(y, z) TRUE ? rnorm(5) : month.abb ## [1] 1.4584104143 0.0007500051 -0.7629123322 0.2433415442 0.0052823403 FALSE ? rnorm(5) : month.abb ## [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"

(Esto funciona porque la precedencia de : es menor que ? )

Lamentablemente, eso rompe la ayuda existente y los operadores de secuencia.


No existe explícitamente, pero puedes hacer:

set.seed(21) y <- 1:10 z <- rnorm(10) condition1 <- TRUE x1 <- if(condition1) y else z

o

condition2 <- sample(c(TRUE,FALSE),10,TRUE) x2 <- ifelse(condition2, y, z)

La diferencia entre los dos es que condition1 debe ser un vector lógico de longitud 1, mientras que condition2 debe ser un vector lógico de la misma longitud que x , y y z . El primero devolverá o y z (el objeto completo), mientras que el segundo devolverá el elemento correspondiente de y ( condition2==TRUE ) o z ( condition2==FALSE ).

También tenga en cuenta que ifelse será más lento que if / else si condition , y y z son todos vectores con longitud 1.


Su enlace apunta a una declaración if .

> x <- 1 > if(x < 2) print("Less than") else print("Greater than") [1] "Less than"

Si su variable de entrada es un vector, ifelse podría ser más adecuado:

> x <- 1:3 > ifelse(x<=2, "Less than or equal", "Greater than") [1] "Less than or equal" "Less than or equal" "Greater than"

Para acceder a la página de ayuda if necesita, inserte el if en los backticks:

?`if`

La página de ayuda para ifelse está en:

`?ifelse`


if works like unvectorised ifelse si se usa de la siguiente manera:

`if`(condition, doIfTrue, doIfFalse)

La ventaja de usar esto sobre ifelse es cuando la vectorización está en el camino (es decir, tengo elementos booleanos escalares y de lista / vector como resultado)

ifelse(TRUE, c(1,2), c(3,4)) [1] 1 `if`(TRUE, c(1,2), c(3,4)) [1] 1 2


ifelse un vistazo al comando ifelse . Yo lo llamaría aún mejor porque también está vectorizado. Un ejemplo con el conjunto de datos de los automóviles:

> cars$speed > 20 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE [49] TRUE TRUE > ifelse(cars$speed > 20, ''fast'', ''slow'') [1] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" [11] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" [21] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" [31] "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" "slow" [41] "slow" "slow" "slow" "fast" "fast" "fast" "fast" "fast" "fast" "fast"