La funzione switch() può essere un sostituto conciso per una lunga serie di controlli if ... else if.
La variabile su cui si effettua lo switch è quasi sempre una stringa e, in questo caso, puoi omettere le virgolette dal selettore.
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"
Nota che le opzioni passano a quella successiva solo se il valore viene lasciato vuoto, come per M nell'esempio qui sopra.
Non c'è bisogno di includere istruzioni break, come avviene in altri linguaggi.
Quando si effettua lo switch su tipi character, il valore finale è quello predefinito, come qui.
Con i tipi integer, invece, non si può indicare alcun valore predefinito.
dplyr
Lo switch di R base è piuttosto limitato: esegue solo una corrispondenza esatta con un singolo input.
Sembrava ragionevole quando R è stato rilasciato per la prima volta nel 1993, ma per l'uso moderno ha bisogno di miglioramenti.
Come accennato nel concetto Conditionals, la raccolta di pacchetti tidyverse è pensata per integrare (e talvolta sostituire) le funzionalità di R base senza compromettere la retrocompatibilità.
Il pacchetto dplyr può essere portato nello scope aggiungendo library(dplyr) (per il singolo pacchetto) oppure library(tidyverse) (per l'intera raccolta) in cima al codice.
La libreria dplyr fornisce due funzioni aggiuntive legate a switch.
recode_values e replace_values
Queste due funzioni correlate consentono una mappatura vettorizzata, simile a uno switch, dai vecchi valori ai nuovi valori.
La differenza principale tra loro è che recode_values() crea un vettore completamente nuovo, mentre replace_values() consente aggiornamenti parziali di un vettore esistente.
La corrispondenza è ancora esatta, ma:
~ invece che con =.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 porta la sintassi di case_match un passo più avanti, consentendo qualsiasi espressione logica a sinistra della ~.
Il vettore di input (x nell'esempio qui sotto) non viene passato come argomento: deve solo essere già definito.
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?"
Anche la funzione between() fa parte di dplyr.
In questo esercizio simuleremo il primo turno di una partita a Blackjack.
Riceverai due carte e potrai vedere la carta scoperta del banco. Tutte le carte sono rappresentate da una stringa come "ace", "king", "three", "two", ecc. I valori di ogni carta sono:
| carta | valore | carta | valore |
|---|---|---|---|
| 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 | altre | 0 |
Nota: di solito gli assi possono valere 1 o 11, ma per semplicità assumeremo che possano valere solo 11.
A seconda delle tue due carte e della carta del banco, esiste una strategia per il primo turno di gioco, che ti offre le seguenti opzioni:
Anche se non è ancora ottimale, seguirai la strategia che il tuo amico Alex sta sviluppando, che è la seguente:
Implementa una funzione parse_card che calcoli il valore numerico di una carta:
parse_card("ace")
# => 11
Scrivi una funzione first_turn che implementi la logica decisionale descritta sopra:
first_turn(card1, card2, dealer_card)
Ecco alcuni esempi dei risultati attesi:
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Iscriviti a Exercism per imparare e padroneggiare R con 21 concetti111 esercizi e il mentoring di persone reali, tutto gratis.