* Plyr.rを読む データを処理したい単位に切り刻む。 そして、処理をする。 処理したデータを、再整形して、array, list, dataframeに戻す。 関数は、xxplyという命名規則?になる。
引数は、 (inputのデータ, データを分割する基準, 分割されたデータを処理する関数)の3つを取る。 4つ目以降は、3つめに入れる関数の引数となる ddply(diamonds, .(color), function(df){ price.sum.byColor = sum(df$price)} ) みたいな形。 3つ目の関数の返り値は、設定する?関数に合わせたものにする。 ddplyなら、dataframeを返す。上記の例の場合だと、暗黙の了解で、データフレームのprice.sum.byColor列が付く) ** 操作系関数 *** subset sqlのgroup_byしてから、selectするイメージ? #select the smallest diamond in each colour ddply(diamonds, .(color), subset, carat=min(carat) #select the two smallest diamonds ddply(diamonds, .(color), subset, order(carat) <=2) #select the 1% largest diamonds in each group ddply(diamonds, .(color), subset, carat > quantile(carat, 0.99)) #select all diamonds bigger than the group average ddply(diamonds, .(color), subset, price > mean(price)) *** transform group別の集計数字を上げて、それを各行に加えるのに便利 単純なtransformでは面倒だけど、、、という場面に。 #within each colour, scale price to mean 0 and variable 1 ddply(diamonds, .(color), transform, price = scale(price)) #Subtract off group mean ddply(diamonds, .(color), transform, price = price - mean(price)) ** tutorialをやる。ozoneの変動 データは、3次元配列(latitude:24levels, longitude:24levels, time:72回by月) ozone[1,1,]で、(1,1)での期間の移り変わりがわかる time <- 1:72/12 で、一年単位のサイクルを作る ** 注意点 a(array), l(list), d(dataframe)の略称を使って、関数を命名してる。 おかげで、とても覚えやすいけど、 a_plyで、インプットはarrayという事ではない。 インプットされるデータが、arrayを処理するような形で、まず切り刻まれるという事。 arrayを処理するような形とは、ある次元を固定して、その単位でデータを切り刻む。 なので、dataframeでも、行ごとに処理したいとかなら、a_plyとかも使える。 で、d_plyを処理するような形もあるわけで、これはある列のデータを、値によるグルーピングという切り刻み方。 ** aaply ほとんどapplyと変わらないけど、arrayで返してくれると嬉しい時もある。 .drop=Fにしたときの表示が apply より親切 ??? : idempotentだと。同じarrayで返してくれる。 marginを指定する => その次元を固定すると頭の中で反芻すると良いかも each(min, max)という使い方もある aaply(ozone, 1, each(min,max)) ** alply リストで返すので、データの塊で返す場合などに使う?例では、テーブルを返す例が表示 alply(ozone, 3, function(x) table(round(x))) ** arrange データフレームの並び替えは mtcars[with(mtcars, order(cyl, disp),] こんな感じらしいけど、 arrange(mtcars, cyl, disp)とか、arrange(mtcars, cyl, desc(disp)) とかで、できる。 ただ、帰ってきてデータフレームのrownames(dataframe)が、数字のものに置き換わってしまう。 ** as.data.frame detailには、This is useful when calling *dply functions with a function that returns a vector, and you want thte output ini rows, rather thatn columns. と書いているけど、よく分かってない。試してない。 ** as.quoted ヘルパー関数みたいなもの? called by default on all plyr funcitons that take a .variables argと書いてある。 ** a_ply ディメンジョンでデータを切って、なんかの処理を副作用的にする。 使いどころは、今は思い浮かばない ** colwise 列別に関数を適用したい。関数をラップしてくれるみたい。 列別のNAの数を調べる > nmissing <- function(x)sum(is.na(x)); colwise(nmissing)(baseball) 年別にNAデータがどこにどれだけあるか調べる > ddply(baseball, .(year), colwise(nmissing)) 二番目以降の引数を指定してら、その列名のみに適用 > ddply(baseball, .(year), colwise(nmissing, .(sb, cs,so))) 結果のdataframeの列名は、sb, cs, soのみ。 文字列データでのNAを調べる > ddply(baseball, .(year), colwise(nmissing, is.character)) ** count tableと似てる。as.data.frame(table(x)) と。 zeroカウントをこっちは入れないと書いてある。 > count(baseball, "id") 選手別のレコード数 > count(count(baseball, c("id","year")), "freq") 選手が同年に複数レコードをもつ(トレードとかで移籍?)数。新しくできるdataframeの列名がfreqなのを利用 ** daply 普通はtapplyを使うような場面は、こちらを使うと良い。 データフレームがあって、その中のある項目の値について分類して、集計した値を出したい。 tapplyは集計対象も指定するけど、こっちなら、まとめて集計してくれる。 > daply(baseball, .(year), mean) これで、すべての項目(year以外)について、year別の平均が出る。 tapplyのことは忘れるべき。 ** dlply * splat do.callを便利にしたもの? do.callは、一行一行に何かをfunctionさせたい時 に使う? その場合の引数の扱いを、splatは優しくしてくれる。 ** each 複数の関数を包んで関数を返してくれる。返してくれた関数に引数を与えて実行すると、中のそれぞれの関数を処理 した結果が帰ってくる。 > each(min, max)(1:10) ** failwith 処理の結果でエラーになった場合に返す値をいれた形で関数をラップする(定義しなおす) > hoge <- function(x) x + 10 > fn <- failwith(NULL, hoge); > fn(0) エラーメッセージが出るが、NULLを受け取って続けられる。 ** idata.frame 実験用機能。data.frameを切り刻むときに、コピーを作るのではなく、参照にとどめておく。効率化が目的。 > system.time(dlply(baseball, "id", nrow)) > system.time(dlply(idata.frame(baseball), "id", nrow)) |