تابع switch() میتواند جایگزینی مختصر برای یک سری طولانی از آزمونهای if ... else if باشد.
متغیری که روی آن switch انجام میشود معمولاً یک رشته است و در این صورت میتوان گیومهها را از انتخابگر حذف کرد.
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() تا در صورتی که قرار است شرطها همهی حالتها را پوشش دهند، خطا پرتاب شود.
switch روی یک عدد صحیح کمی متفاوت است: در این حالت پیشفرض همیشه NULL است (که در مفهوم نیستی به آن پرداخته خواهد شد).
dplyr
switch در R پایه نسبتاً محدود است: فقط یک تطابق دقیق با یک ورودی واحد انجام میدهد.
این در سال ۱۹۹۳ که R برای نخستین بار منتشر شد معقول به نظر میرسید، اما برای استفادهی امروزی به بهبود نیاز دارد.
همانطور که در مفهوم 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
شاید آنلاین توصیههایی ببینید دربارهی استفاده از تابع case_match() بهعنوان یک switch برداری.
این تابع در نسخهی ۱.۲.۰ بستهی dplyr (فوریه ۲۰۲۶) منسوخ شد.
تلاش برای استفاده از آن اکنون یک پیام هشدار تولید میکند که به استفاده از 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"