switch () penggunaan pernyataan


106

Saya sedikit bingung tentang pernyataan switch di R. Cukup googling fungsinya saya mendapatkan contoh sebagai berikut:

Penggunaan umum dari sakelar adalah untuk bercabang sesuai dengan nilai karakter dari salah satu argumen ke suatu fungsi.

 > 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

Namun ini sepertinya sama dengan hanya memiliki sekumpulan ifpernyataan yang ditujukan untuk masing-masingtype

Apakah hanya itu yang bisa dilakukan switch()? Bisakah seseorang memberi saya contoh lebih lanjut dan aplikasi yang lebih baik?


10
Ya, itu saja.
— Andrie

Jawaban:


119

Nah, waktu untuk menyelamatkannya lagi. Tampaknya switchsecara umum lebih cepat daripada ifpernyataan. Sehingga, dan fakta bahwa kodenya lebih pendek / rapi dengan switchpernyataan bersandar pada 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

Perbarui Dengan mengingat komentar Joshua, saya mencoba cara lain untuk melakukan benchmark. Microbenchmark sepertinya yang terbaik. ... dan itu menunjukkan pengaturan waktu yang serupa:

> 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

Pembaruan Terakhir Berikut ini menunjukkan betapa serbaguna switch:

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

Ini memetakan case2dan case3ke 2.5dan (tanpa nama) default ke 99. Untuk informasi lebih lanjut, coba?switch


3
Menggunakan perulangan for seperti itu dapat menyebabkan masalah dengan pengumpulan sampah. Perbedaannya adalah jauh lebih kecil dengan fungsi pembandingan yang lebih baik: benchmark(test1('trimmed'), test2('trimmed'), replications=1e6).
— Joshua Ulrich

@JoshuaUlrich ... benchmarkfungsi apa yang Anda gunakan? Bukan yang jelas dari paket "patokan" sepertinya?
— Tommy

1
Menurut stackoverflow.com/questions/6262203/… "microbenchmark" bahkan lebih baik.
— Tommy

@JoshuaUlrich - Saya memperbarui jawaban dengan hasil dari microbencmark, tetapi hasilnya sangat mirip dengan yang asli. Saya tidak benar-benar melihat bagaimana rbenchmark akan mengatasi masalah GC, tetapi tampaknya memiliki lebih banyak overhead dengan menelepon evaldan replicate.
— Tommy

sama seperti di samping dapatkah saya memiliki beberapa casing dengan output yang sama? yaituswitch(type, c(this,that)=do something)
— LostLin

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.