tapplyの再実装で高速化
applyとかtapplyとか遅い。Rcppで楽したい。けど苦労はしたくない。
そんなときKmiscパッケージのrcpp_tapply_generator関数が役に立ちます。
使い方は簡単。tapply関数のFUNをreturnとともに放り込むだけ。
install.packages("Kmisc") library(Kmisc) cppTapply <- rcpp_tapply_generator("return mean(x);")
速さを測ってみます。
install.packages("microbenchmark") library(microbenchmark) microbenchmark( tapply(iris$Sepal.Length, iris$Species, mean), cppTapply(iris$Sepal.Length, iris$Species), iris %>% group_by(Species) %>% summarise(mean(Sepal.Length)) )
結果はこちら。tapply、dplyrと比較してみます。
Unit: microseconds expr min lq mean median uq max neval cppTapply(iris$Sepal.Length, iris$Species) 58.164 69.6605 88.51962 81.5005 97.1935 246.737 100 tapply(iris$Sepal.Length, iris$Species, mean) 197.400 208.8065 238.16384 228.1135 245.9890 456.475 100 iris %>% group_by(Species) %>% summarise(mean(Sepal.Length)) 850.581 958.0700 1013.35200 986.1895 1025.5135 1731.105 100
速い!!!
ちなみにKmiscパッケージにはtapply_という関数も用意されています。
こちらは高速化を図ってtapplyを再実装したもの。
使い方はtapplyと同じ。
Unit: microseconds expr min lq mean median uq max neval tapply_(iris$Sepal.Length, iris$Species, mean) 69.436 79.5705 90.45106 84.4310 97.9000 146.773 100 cppTapply(iris$Sepal.Length, iris$Species) 58.522 68.2020 79.83578 76.7925 86.0465 140.197 100 tapply(iris$Sepal.Length, iris$Species, mean) 198.723 217.0880 235.40915 233.7335 247.2670 378.604 100 iris %>% group_by(Species) %>% summarise(mean(Sepal.Length)) 886.211 1006.8870 1039.99144 1036.3295 1064.0005 1360.138 100
そんなに変わらない気がするのでtapply_でいいかもしれません。
enjoy!!!