[R] 변환 함수 _ Switch

DongGyu Jung·2021년 9월 28일
0

Switch

말 그대로 값 변환에 사용되는 함수이다.
개인적으로 평가할 값을 투입한 후,
조건과 할당 값을 미리 지정하여 투입 값을 평가하여 변환해주는 식이라고 생각한다.

간단히 말하자면
투입 값(input_EXPR 인수 Value)이 숫자이던 문자이던
문자열로 변환하여 특정 문자에 부합할 경우 설정한 값으로 변환하는 함수라고 할 수 있다.


우선 함수의 구조를 살펴보자.

Switch( EXPR = [평가값], (경우a) =, (경우b) = ,... (경우x) = [변환값] )

EXPR 인수는 필수 인수로서 "평가값"을 입력받는 인수이다.

이후,
평가 기준이 될 '경우의 수'
즉, 비교값을 지정해주는데 = 를 붙힌 후에 나열해주어야하며,
변환값은 마지막 나열되는 비교값의 "="에 이어붙혀 입력하면 된다.
(변환값의 구분 방법은 '='으로 연결되는 마지막 값을 기준으로 분류된다.)



소소한 예제로 살펴보자.

month <- sample(1:12,1)
# 비교값은 공백이 없기 때문에 sep="" 설정 ("3 월" -> "3월")
month <- paste(month,"월",sep="")

#마지막 아무 비교값 없는 "가을"은 if문에서의 "else"의 return값의 역할이다. 
result <- switch(EXPR=month,
                 "12월"=,"1월"=,"2월"="겨울",
                 "3월"=,"4월"=,"5월"="봄",
                 "6월"=,"7월"=,"8월"="여름",
                 "가을")
cat(month,"은 ",result,"입니다\n",sep="")

이렇게 EXPR인수로 값을 받는 함수이기때문에

사용자의 입력을 받는 함수인
readline(prompt="") 등의 입력 함수
sample() Random 함수, for문 등에서 활용하기 좋다.


*Random 함수 / For문 활용

정수 값이 사용될 때 주의할 점이 있다.😂
switch에서 비교값을 지정하지 않고 변환값만 지정하게 된다면
자동으로 첫 번째 변환값에 1부터 차례대로 할당된다.

즉, 1:10으로 1~10의 10개의 연속적인 수가 입력되는데
아래와 같이 변환값이 4개밖에 지정되지 않았다면 [1~4 ] 까지만 변환이 이루어지고
[5~10 ]까지의 정수들에는 할당된 값이 없기때문에 NA 처리 된다.

num <- sample(1:10,1)
num
switch(EXPR = num,"A","B","C","D")

또한,
입력되는 값의 수보다 비교 값의 수가 적을 경우,
해당되는 값만 변환 되고 나머지는 모두 NA 처리 된다.

for(num in 1:10){
  cat(num,":",switch(EXPR = num,"A","B","C","D"),"\n")
}

1 : A 
2 : B 
3 : C 
4 : D 
5 : 
6 : 
7 : 
8 : 
9 : 
10 : 

그렇기 때문에 할당되지 않는 경우를 대비하여
마지막 순서"비교값 없는 변환값" 을 입력하여 "나머지의 투입값들의 변환값"으로 지정한다.

for(num in 1:10){
  num <- as.character(num) 
  cat(num,":",switch(EXPR = num,
                     "10"="A","9"="B","8"="C","7"="D","F"),"\n")
}

1 : F 
2 : F 
3 : F 
4 : F 
5 : F 
6 : F 
7 : D 
8 : C 
9 : B 
10 : A 

생각보다 까다로운(?) Switch 함수의 특성을 조금 활용해보자면
사용자 정의 함수 혹은 IF문 등에서 조건 변환 기능을 부여할 수 있다.

예를 들어,
"인수로 문자열을 받아 조건에 맞는 경우, 특정 문자로 변환하는 함수" 를 만든다면
아래와 같이 사용할 수 있다.

# 인수 n,m 은 숫자값을 받는 인수
calc <- function(n,op,m){
# %in% : 다중 선택자
  if (op %in% c("+","-","*","%/%","%%","/")){
  # 몫 과 나머지 연산자의 경우 0이 입력되는 것 방지
    if(op == "%/%" || op == "%%"){
      if(n == 0){
        return("오류1")
      }else if (m == 0){
        return("오류2")
      }else{
        return(switch(EXPR = op, "%/%" = n%/%m, "%%" = n%%m))
      }
    }else{
      return(switch(EXPR = op, "+" = n+m,"-" = n-m,"*" = n*m, "/" = n/m))
    }
  }else{
    return("규격의 연산자만 전달하세요")
  }
}

> calc(10,"/",5)
[1] 2
> calc(10,"+",5)
[1] 15
> calc(10,"-",5)
[1] 5
> calc(10,"*",5)
[1] 50
> calc(10,"/",5)
[1] 2
> calc(10,"%/%",5)
[1] 2
> calc(10,"%%",5)
[1] 0
> calc(10,"$",5)
[1] "규격의 연산자만 전달하세요"

단순 변환 함수인 replace() 함수와는 다르게 식 변환 등이 가능하니
다방면으로 활용할 수 있는 함수라고 생각한다.

0개의 댓글