Sw

Switch en R

1 exercice

À propos de Switch

La fonction switch() peut remplacer de façon concise une longue série de tests if ... else if. La variable testée est le plus souvent une string, auquel cas on peut omettre les guillemets dans le sélecteur.

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"

À noter qu'une option ne passe à la suivante que si sa valeur est laissée vide, comme pour M dans l'exemple ci-dessus. Il n'est pas nécessaire d'inclure des instructions break comme dans certains autres langages.

La dernière valeur peut être une valeur par défaut, comme ici, ou un stop() servant à lever une erreur si les conditions sont censées être exhaustives. Faire un switch sur un entier est légèrement différent : dans ce cas, la valeur par défaut est toujours NULL (ce point sera abordé dans le concept Néant).

Les fonctions dans dplyr

La fonction switch de R de base est assez limitée : elle ne fait qu'une correspondance exacte sur une seule entrée. Cela semblait raisonnable à la sortie de R en 1993, mais mérite des améliorations pour un usage moderne.

Note

Comme mentionné dans le concept Conditionals, la collection de paquets tidyverse est conçue pour compléter (et parfois remplacer) les fonctionnalités de R de base sans nuire à la rétrocompatibilité.

Les paquets du tidyverse disposent eux aussi d'une excellente documentation moderne : les liens ci-dessous t'en diront plus.

Le paquet dplyr peut être chargé en ajoutant library(dplyr) (pour ce seul paquet) ou library(tidyverse) (pour toute la collection) en haut de ton code.

La bibliothèque dplyr fournit deux fonctions supplémentaires liées à switch.

Les fonctions recode_values et replace_values

Ces deux fonctions apparentées permettent une correspondance vectorisée, à la manière de switch, entre d'anciennes et de nouvelles valeurs.

La principale différence entre elles est que recode_values() crée un vecteur entièrement nouveau, tandis que replace_values() permet de mettre à jour partiellement un vecteur existant.

La correspondance reste exacte, mais :

  • Les options à gauche peuvent être des vecteurs, et l'entrée correspond si l'un de ses éléments correspond.
  • Les options à gauche et les résultats à droite sont reliés par un tilde ~ au lieu du signe =.
  • Les valeurs manquantes NA peuvent être mises en correspondance explicitement (ce point sera abordé dans le concept Néant).
  • Une valeur par défaut peut être spécifiée dans tous les cas.
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

Tu trouveras peut-être en ligne des conseils recommandant d'utiliser la fonction case_match() comme un switch vectorisé.

Cette fonction a été dépréciée dans la version 1.2.0 de dplyr (février 2026). Toute tentative d'utilisation produit désormais un message d'avertissement qui conseille d'utiliser plutôt recode_values().

La fonction case_when

case_when pousse la syntaxe de case_match un cran plus loin, en autorisant n'importe quelle expression logique à gauche du ~.

Le vecteur d'entrée (x dans l'exemple ci-dessous) n'est pas fourni comme argument : il doit simplement être déjà défini.

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 fonction between() fait elle aussi partie de dplyr.

Les fonctions sur les strings ont déjà été abordées et les expressions régulières feront l'objet d'un concept ultérieur. Celles-ci se combinent très bien avec 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"
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Switch