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).
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.
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.
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 :
~ au lieu du signe =.NA peuvent être mises en correspondance explicitement (ce point sera abordé dans le concept Néant).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
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().
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"