sw

switch 에서 R

1개의 연습 문제

switch 소개

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이에요. (Nothingness 개념에서 다뤄요.)

dplyr의 함수들

base R의 switch는 꽤 제한적이에요. 단일 입력에 대한 정확한 일치만 처리해요. 1993년 R이 처음 공개됐을 때는 합리적으로 보였지만, 현대적인 사용에는 개선이 필요해요.

Note

Conditionals 개념에서 언급했듯이, tidyverse 패키지 모음은 base R의 기능을 보완하고(때로는 대체하고) 하위 호환성에 영향을 주지 않도록 설계됐어요.

tidyverse 패키지들은 훌륭한 최신 문서도 갖추고 있어서, 아래 링크를 따라가면 더 자세한 내용을 볼 수 있어요.

코드 맨 위에 library(dplyr)(단일 패키지용)나 library(tidyverse)(전체 모음용)를 추가하면 dplyr 패키지를 스코프 안으로 불러올 수 있어요.

dplyr 라이브러리는 switch와 관련된 두 가지 추가 함수를 제공해요.

recode_values와 replace_values 함수

이 두 함수는 서로 관련이 있고, 예전 값을 새 값으로 매핑하는 벡터화된 switch 같은 기능을 제공해요.

둘의 주요 차이는 recode_values()는 완전히 새로운 벡터를 만들고, replace_values()는 기존 벡터를 부분적으로 갱신할 수 있다는 점이에요.

일치는 여전히 정확하지만, 다음이 달라요:

  • 왼쪽의 옵션은 벡터가 될 수 있고, 어떤 원소라도 일치하면 입력이 일치한 것으로 봐요.
  • 왼쪽의 옵션과 오른쪽의 결과는 = 대신 물결표 ~로 연결해요.
  • 결측값 NA도 명시적으로 일치시킬 수 있어요. (Nothingness 개념에서 다뤄요.)
  • 모든 경우에 기본값을 지정할 수 있어요.
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년 2월)에서 폐기됐어요. 이제 이 함수를 사용하려 하면 경고 메시지가 나오고, 대신 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에서 편집 링크가 새 창이나 탭에서 열려요

switch 배우기