Треки
/
R
R
/
Салабус
/
Перемикач
Пе

Перемикач у R

1 вправа

Про концепцію Перемикач

Функція switch() може стати лаконічною заміною довгого ланцюжка перевірок if ... else if. Змінна, за якою виконується перемикання, найчастіше буває рядком тексту (англ. string), і в такому разі лапки в селекторі можна не писати.

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"

Зауважмо, що варіанти «провалюються» далі лише тоді, коли значення залишено порожнім, як у випадку з M у прикладі вище. Тут не потрібно додавати інструкції break, як у деяких інших мовах.

Останнє значення може бути типовим, як ось тут, або викликом stop(), щоб згенерувати помилку, коли умови мають охоплювати всі можливі випадки. Перемикання за цілим числом трохи відрізняється: для них типовим значенням завжди є NULL (про це йтиметься в концепції «Порожнеча»).

Функції в dplyr

switch у базовому R досить обмежений: він уміє лише точно зіставляти з одним вхідним значенням. Це здавалося розумним, коли R уперше випустили 1993 року, але для сучасного використання його потрібно вдосконалити.

Note

Як зазначалося в концепції Conditionals, набір пакетів tidyverse покликаний доповнювати (а іноді й замінювати) можливості базового R, не порушуючи зворотної сумісності.

Пакети tidyverse також мають чудову сучасну документацію, тож за посиланнями нижче можна дізнатися більше.

Щоб зробити пакет dplyr доступним, додамо library(dplyr) (для одного пакета) або library(tidyverse) (для всього набору) на початку коду.

Бібліотека dplyr надає дві додаткові функції, повʼязані зі switch.

Функції recode_values та replace_values

Ці дві споріднені функції дають змогу векторно зіставляти старі значення з новими, подібно до switch.

Головна відмінність між ними полягає в тому, що recode_values() створює цілком новий вектор, а replace_values() дає змогу частково оновлювати наявний вектор.

Зіставлення все ще відбувається за точним збігом, але:

  • Варіанти ліворуч можуть бути векторами, і вхідне значення вважається зіставленим, якщо збігається хоча б один елемент.
  • Варіанти ліворуч і результати праворуч зʼєднуються тильдою ~, а не знаком =.
  • Пропущені значення NA можна зіставляти явно (про це йтиметься в концепції «Порожнеча»).
  • Типове значення можна задати в усіх випадках.
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

В інтернеті можна натрапити на поради використовувати функцію case_match() як векторний switch.

Цю функцію визнано застарілою в dplyr версії 1.2.0 (лютий 2026). Спроби скористатися нею тепер видаватимуть попередження з порадою натомість використовувати recode_values().

Функція case_when

case_when розвиває синтаксис case_match далі, дозволяючи будь-який логічний вираз ліворуч від ~.

Вхідний вектор (x у прикладі нижче) не передається як аргумент, він просто має бути вже визначений.

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?"

Функція between() також входить до dplyr.

Про рядкові функції уже йшлося, а регулярні вирази стануть темою однієї з наступних концепцій. Вони дуже добре поєднуються з 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"
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Перемикач