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 문을 넣을 필요는 없어요.
character 타입을 검사할 때는 여기에서처럼 마지막 값이 기본값이 돼요.
정수 타입에서는 기본값을 지정할 수 없어요.
dplyr의 함수들base R의 switch는 꽤 제한적이에요. 단일 입력에 대한 정확한 일치만 처리해요.
1993년 R이 처음 공개됐을 때는 합리적으로 보였지만, 현대적인 사용에는 개선이 필요해요.
Conditionals 개념에서 언급했듯이, tidyverse 패키지 모음은 하위 호환성에 영향을 주지 않으면서 base R의 기능을 보완하고(때로는 대체하도록) 설계됐어요.
dplyr 패키지는 코드 맨 위에 library(dplyr)(패키지 하나만 쓸 때) 또는 library(tidyverse)(모음 전체를 쓸 때)를 추가해서 스코프로 불러올 수 있어요.
dplyr 라이브러리는 switch와 관련된 두 가지 추가 함수를 제공해요.
recode_values와 replace_values 함수이 두 함수는 서로 관련이 있으며, 기존 값을 새 값으로 매핑하는, switch와 비슷하지만 벡터화된 기능을 제공해요.
둘의 가장 큰 차이는 recode_values()는 완전히 새로운 벡터를 만들고, replace_values()는 기존 벡터의 일부만 갱신할 수 있다는 점이에요.
일치는 여전히 정확히 이루어져요. 다만:
= 대신 물결표 ~로 연결해요.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_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의 일부예요.
이 연습 문제에서는 블랙잭 게임의 첫 턴을 시뮬레이션해 볼 거예요.
두 장의 카드를 받고, 딜러의 카드 중 앞면이 보이는 한 장을 볼 수 있어요. 모든 카드는 "ace", "king", "three", "two" 같은 문자열로 표현해요. 각 카드의 값은 다음과 같아요:
| 카드 | 값 | 카드 | 값 |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | other | 0 |
참고: 일반적으로 에이스는 1 또는 11의 값을 가질 수 있지만, 단순화를 위해 여기서는 11의 값만 가진다고 가정해요.
두 장의 카드와 딜러의 카드에 따라 게임의 첫 턴에 적용할 전략이 있고, 선택지는 다음과 같아요:
아직 최적은 아니지만, 친구 Alex가 개발해 온 전략을 따라갈 거예요. 그 전략은 다음과 같아요:
카드의 숫자 값을 계산하는 parse_card 함수를 구현해요:
parse_card("ace")
# => 11
위에서 설명한 판단 로직을 구현하는 first_turn 함수를 작성해요:
first_turn(card1, card2, dealer_card)
예상 결과의 몇 가지 예시는 다음과 같아요:
first_turn("ace", "ace", "jack") == "P"
first_turn("ace", "king", "ace") == "S"
first_turn("five", "queen", "ace") == "H"
Exercism에 가입하고 R 트랙을 개념 21개연습 문제 111개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.