switch () 문 사용법


106

R의 switch 문에 대해 약간 혼란 스럽습니다. 함수를 검색하면 다음과 같은 예제가 표시됩니다.

스위치의 일반적인 사용은 함수에 대한 인수 중 하나의 문자 값에 따라 분기하는 것입니다.

 > centre <- function(x, type) {
 + switch(type,
 +        mean = mean(x),
 +        median = median(x),
 +        trimmed = mean(x, trim = .1))
 + }
 > x <- rcauchy(10)
 > centre(x, "mean")
 [1] 0.8760325
 > centre(x, "median")
 [1] 0.5360891
 > centre(x, "trimmed")
 [1] 0.6086504

그러나 이것은 단지 if각각에 대해 지정된 진술을 갖는 것과 동일하게 보입니다.type

그게 전부 switch()입니까? 누군가 나에게 더 많은 예제와 더 나은 응용 프로그램을 줄 수 있습니까?


10
예, 그게 전부입니다.
Andrie

답변:


119

글쎄, 다시 구출 타이밍. 보인다 switch일반적으로 빨리보다 if문. 그래서 코드가 더 짧고 깔끔하다는 사실은 다음 switch을 선호합니다 switch.

# Simplified to only measure the overhead of switch vs if

test1 <- function(type) {
 switch(type,
        mean = 1,
        median = 2,
        trimmed = 3)
}

test2 <- function(type) {
 if (type == "mean") 1
 else if (type == "median") 2
 else if (type == "trimmed") 3
}

system.time( for(i in 1:1e6) test1('mean') ) # 0.89 secs
system.time( for(i in 1:1e6) test2('mean') ) # 1.13 secs
system.time( for(i in 1:1e6) test1('trimmed') ) # 0.89 secs
system.time( for(i in 1:1e6) test2('trimmed') ) # 2.28 secs

업데이트 Joshua의 의견을 염두에두고 다른 방법으로 벤치마킹을 시도했습니다. 마이크로 벤치 마크가 가장 좋은 것 같습니다. ... 그리고 유사한 타이밍을 보여줍니다.

> library(microbenchmark)
> microbenchmark(test1('mean'), test2('mean'), times=1e6)
Unit: nanoseconds
           expr  min   lq median   uq      max
1 test1("mean")  709  771    864  951 16122411
2 test2("mean") 1007 1073   1147 1223  8012202

> microbenchmark(test1('trimmed'), test2('trimmed'), times=1e6)
Unit: nanoseconds
              expr  min   lq median   uq      max
1 test1("trimmed")  733  792    843  944 60440833
2 test2("trimmed") 2022 2133   2203 2309 60814430

최종 업데이트 다재다능한 기능을 보여줍니다 switch.

switch(type, case1=1, case2=, case3=2.5, 99)

이 매핑 case2case32.5및 (이름 없음) 기본값은 99. 자세한 내용은?switch


3
이와 같은 for 루프를 사용하면 가비지 수집에 문제가 발생할 수 있습니다. 더 나은 벤치마킹 기능을 사용하면 차이가 훨씬 적습니다 benchmark(test1('trimmed'), test2('trimmed'), replications=1e6).
Joshua Ulrich

@JoshuaUlrich ... 어떤 benchmark기능을 사용하고 있습니까? "benchmark"패키지의 명백한 것이 아닌 것 같습니까?
Tommy

1
stackoverflow.com/questions/6262203/ 에 따르면… "microbenchmark"가 더 나은 것입니다.
Tommy

@JoshuaUlrich-의 결과로 답변을 업데이트 microbencmark했지만 원래 결과와 매우 유사합니다. rbenchmark가 GC 문제를 어떻게 해결하는지 실제로는 알 수 없지만 evalreplicate.
Tommy

제쳐두고 동일한 출력으로 여러 케이스를 가질 수 있습니까? 즉switch(type, c(this,that)=do something)
LostLin

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.