La función switch() puede ser un reemplazo conciso para una larga serie de pruebas if ... else if.
La variable sobre la que se hace el switch suele ser un string y, en ese caso, las comillas se pueden omitir del selector.
star <- function(type) {
switch(type,
M = , # will "fall through" if no value given
K = "red dwarf",
G = "Earth-like",
"bigger star" # only correct for O,B,A,F
)
}
> star("M")
[1] "red dwarf"
Fíjate que solo se pasa a la siguiente opción si el valor se deja en blanco, como con M en el ejemplo anterior.
No es necesario incluir sentencias break, como sí ocurre en otros lenguajes.
Cuando se hace un switch sobre tipos character, el valor final es un valor predeterminado, como aquí.
Con tipos enteros, no se puede dar un valor predeterminado.
dplyr
El switch de R base es bastante limitado: solo hace una coincidencia exacta con un único argumento.
Esto parecía razonable cuando R se lanzó por primera vez en 1993, pero necesita mejoras para el uso moderno.
Como se mencionó en el ejercicio de concepto Conditionals, la colección de paquetes tidyverse está diseñada para complementar (y a veces reemplazar) la funcionalidad de R base sin afectar la compatibilidad con versiones anteriores.
Puedes traer el paquete dplyr al ámbito agregando library(dplyr) (para el paquete individual) o library(tidyverse) (para toda la colección) al inicio de tu código.
La biblioteca dplyr ofrece dos funciones adicionales relacionadas con switch.
recode_values y replace_values
Estas dos funciones relacionadas permiten un mapeo vectorizado, similar a un switch, de valores antiguos a valores nuevos.
La principal diferencia entre ellas es que recode_values() crea un vector completamente nuevo, mientras que replace_values() permite actualizaciones parciales de un vector existente.
La coincidencia sigue siendo exacta, pero:
~ en lugar de =.library(dplyr)
x <- c("a", "b", "a", "d", "b", NA, "c", "e", "z")
recode_values(
x,
"a" ~ 1,
"b" ~ 2,
"c" ~ 3,
c("d", "e") ~ 4, # either "d' or "e" will match
NA ~ 0, # matches missing values
default = 100 # note the different syntax for the default
)
#> [1] 1 2 1 4 2 0 3 4 100
case_when
case_when lleva la sintaxis de case_match un paso más allá, al permitir cualquier expresión lógica a la izquierda del ~.
El vector de valores (x en el ejemplo siguiente) no se pasa como argumento; solo necesita estar ya definido.
x <- 1:10
case_when(
x < 3 ~ "low",
between(x, 3, 5) ~ "mid",
between(x, 6, 8) ~ "high",
.default = "what?"
)
#> [1] "low" "low" "mid" "mid" "mid" "high" "high" "high" "what?" "what?"
La función between() también forma parte de dplyr.
En este ejercicio vamos a simular el primer turno de una partida de Blackjack.
Recibirás dos cartas y podrás ver la carta descubierta del crupier. Todas las cartas se representan con un string como «ace», «king», «three», «two», etc. Los valores de cada carta son:
| carta | valor | carta | valor |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | otra | 0 |
Nota: Por lo general, los ases pueden tomar el valor de 1 o 11, pero por simplicidad asumiremos que solo pueden tomar el valor de 11.
Según tus dos cartas y la carta del crupier, hay una estrategia para el primer turno del juego, en la que tienes las siguientes opciones:
Aunque todavía no es óptima, vas a seguir la estrategia que tu amigo Alex ha estado desarrollando, que es la siguiente:
Implementa una función parse_card para calcular el valor numérico de una carta:
parse_card("ace")
# => 11
Escribe una función first_turn que implemente la lógica de decisión descrita arriba:
first_turn(card1, card2, dealer_card)
Aquí tienes algunos ejemplos de los resultados esperados:
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Regístrate en Exercism para aprender y dominar R con 21 conceptos111 ejercicios y mentoría humana real, todo gratis.