算額あれこれ

算額問題をコンピュータで解きます

plyr なんて...(その2)

ある変数が取る値ごとに,別の変数の平均値と標準偏差を求めるという例題

> f1 = function() ddply(aq, .(Month), summarize, AveTemp=mean(Temp), SdTemp=sd(Temp))
> (ans = f1())
  Month  AveTemp   SdTemp
1     5 65.54839 6.744490
2     6 79.10000 6.488762
3     7 83.90323 4.246023
4     8 83.96774 6.479216
5     9 76.90000 8.216599
>
> # 最後の row.names=NULL は,行名を通し番号にするため
> f2 = function() {
+     a = t(sapply(split(aq$Temp, aq$Month), function(x) c(mean(x), sd(x))))
+     data.frame(Month=as.integer(rownames(a)), AveTemp=a[,1], SdTemp=a[,2], row.names=NULL)
+ }
> identical(ans, f2())
[1] TRUE
>
> # f2 と同じくらい速い
> f3 = function() {
+     a = split(aq$Temp, aq$Month)
+     data.frame(Month=as.integer(names(a)), AveTemp=sapply(a, mean), SdTemp=sapply(a, sd), row.names=NULL)
+ }
> identical(ans, f3())
[1] TRUE
>
> # ddply を使った f1 は,ほぼ 3 倍遅い
> benchmark(f1(), f2(), f3(), columns=c("test", "replications", "elapsed", "relative", "user.self", "sys.self"), replications=1000, order=NULL)
  test replications elapsed relative user.self sys.self
1 f1()         1000   5.824    3.274     5.634    0.225
2 f2()         1000   1.779    1.000     1.725    0.062
3 f3()         1000   1.793    1.008     1.708    0.098