読者です 読者をやめる 読者になる 読者になる

複数の関数を適用した結果を返すeach関数

R

Rであるデータに対して、複数の処理をして、その結果をまとめて返すというのはlist関数を使うのが定石だと思うんだが、若干めんどくさいところがある。例えば無名関数でやるとこんな感じ。

> (function(x){list(mean(x), var(x))})(1:10)
[[1]]
[1] 5.5

[[2]]
[1] 9.166667

しかし、plyrというパッケージのeach関数を使うともっと直感的に書ける。これはよい。

> library(plyr)
> each(mean, var)(1:10)
    mean      var 
5.500000 9.166667 

色々試してみると無名関数をeachには渡せないようである。関数の中身を見てみると、内部で独自な感じのapply系の関数を使っているようだ。

listも使わず、eachも使わないという謎の縛りで、同じようにやるとしたらこんな感じかなー。

> mapply(function(f){do.call(f, list(1:10))}, list(mean=mean, var=var))
    mean      var 
5.500000 9.166667 

本当は

(mapply(function(f){
  function(x){
    do.call(f, list(x))
  }
}, list(mean=mean, var=var)))(1:10)

という感じで書きたいけど、これだと怒られますよねー。遅延評価をうまく利用しないといけない予感。

追記

each関数を実装してみた。

> each <- function(...){
+   function(x) {mapply(function(f){do.call(f, list(x))}, list(...))}
+ }
> each(mean, var)(1:10)
[1] 5.500000 9.166667

おおー、なかなかすごい気がする。どうせなので、ワンライナーで。

> ((function(...){function(x) {mapply(function(f){do.call(f, list(x))}, list(...))}})(mean, var))(1:10)
[1] 5.500000 9.166667

やったー、一行で実装できたよー!!