Sw

Switch in R

1 esercizio

Informazioni su Switch

La funzione switch() può sostituire in modo conciso una lunga serie di test if ... else if. La variabile su cui si fa lo switch è molto spesso una stringa e, in quel caso, è possibile 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"

Tieni presente che si passa all'opzione successiva solo quando il valore è lasciato vuoto, come nel caso di M nell'esempio qui sopra. Non serve includere istruzioni break, come invece accade in altri linguaggi.

L'ultimo valore può essere un valore predefinito, come in questo caso, oppure una chiamata a stop() per generare un errore se le condizioni devono coprire tutti i casi possibili. Lo switch su un numero intero è leggermente diverso: in quel caso il valore predefinito è sempre NULL (ne parleremo nel concetto di Nulla).

Le funzioni in dplyr

Lo switch di base R è 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 servono miglioramenti.

Note

Come accennato nel concetto Conditionals, la raccolta di pacchetti tidyverse è progettata per integrare (e a volte sostituire) le funzionalità di base R senza compromettere la compatibilità con il passato.

I pacchetti del tidyverse hanno anche un'ottima documentazione moderna, quindi seguendo i link qui sotto troverai maggiori dettagli.

Puoi portare il pacchetto dplyr nello scope aggiungendo all'inizio del codice library(dplyr) (per il singolo pacchetto) oppure library(tidyverse) (per l'intera raccolta).

La libreria dplyr fornisce due funzioni aggiuntive legate a switch.

Le funzioni recode_values e replace_values

Queste due funzioni correlate permettono di mappare i vecchi valori su quelli nuovi in modo vettorizzato, simile a uno switch.

La differenza principale tra le due è che recode_values() crea un vettore completamente nuovo, mentre replace_values() permette aggiornamenti parziali di un vettore esistente.

La corrispondenza è comunque esatta, ma:

  • Le opzioni a sinistra possono essere vettori e l'input corrisponde se corrisponde almeno un elemento.
  • Le opzioni a sinistra e i risultati a destra sono collegati con una tilde ~ invece che con =.
  • I valori mancanti NA possono essere confrontati esplicitamente (ne parleremo nel concetto Nulla).
  • In tutti i casi è possibile specificare un valore predefinito.
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
Note

Potresti trovare consigli online sull'uso della funzione case_match() come switch vettorizzato.

Questa funzione è stata deprecata in dplyr versione 1.2.0 (febbraio 2026). I tentativi di usarla ora producono un messaggio di avviso che consiglia di usare recode_values().

La funzione case_when

case_when porta la sintassi di case_match un passo avanti, permettendo qualsiasi espressione logica a sinistra della ~.

Il vettore di input (x nell'esempio 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.

Le funzioni per le stringhe sono già state trattate, mentre le espressioni regolari saranno l'argomento di un concetto successivo. Si combinano molto bene con case_when.

library(stringr)

tracks <- "R C Python C# Elixir C++ Odin" |> str_split_1(" ")
tracks
#> [1] "R"      "C"      "Python" "C#"     "Elixir" "C++"    "Odin"  

case_when(
  str_starts(tracks, "C") ~ "C-like",
  str_starts(tracks, "[AEIOU]") ~ "vowel",
  .default = "other"
)
#> [1] "other"  "C-like" "other"  "C-like" "vowel"  "C-like" "vowel"
Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda

Impara Switch