data.tableでmelt的な処理をしたい
Rの話です.
ggplotしたいのでreshape2のmeltをする場面って結構ありますよね.
meltはdataframeの処理です.
しかし, 時は2014年. dataframeからdata.tableに移行していきたいですよね.
http://cran.r-project.org/web/packages/data.table/vignettes/datatable-intro.pdf
今回は, data.tableでmelt的な処理をします.
data.tableでmelt的な処理
トライアスロンの記録が入っているcsvがありました.
http://chrisladroue.com/files/stratford.csv
これを例に取ります.
まずは読み込み. freadにアドレスを渡すだけです.
> library(data.table) > times = fread(http://chrisladroue.com/files/stratford.csv) > times[,list(Position, Swim, Cycle, Run, Total)] Position StartingPosition StartingTime Age Category Swim Cycle Run Total 1: 1 441 08:44:45 32 F 00:06:04 00:36:46 00:19:11 01:02:01 2: 2 5 08:46:00 35 G 00:05:55 00:37:23 00:20:18 01:03:36 3: 3 26 08:56:00 23 D 00:06:28 00:37:39 00:19:30 01:03:37 4: 4 443 10:35:30 31 F 00:20:51 01:04:09 5: 5 445 10:36:00 27 E 00:06:43 00:37:26 00:21:36 01:05:45 --- 389: 389 24 08:50:45 32 F 02:12:32 390: 390 253 09:48:00 31 F 00:06:52 02:41:39 391: 391 45 08:56:00 39 G 03:24:28 392: 392 46 08:56:15 42 H 03:29:02 393: 393 8 08:46:45 35 G 03:49:43
トライアスロンなので, 水泳, 自転車, マラソン, 総合タイムと総合順位が入っています.
最後の方はNAばかりです. 途中棄権ですね.
各種目の名前を列に入れて,
時間を新しく列に入れたデータのほうが扱いやすいことがあります. ggplotしたいときとか.
今までなら, reshape2のmeltを使います.
> library(reshape2) >meltedTimes<-melt( times, c("StartingPosition","Category","Position"), c("Swim","Cycle","Run","Total"), variable_name="Discipline") >head(meltedTimes) StartingPosition Category Position Discipline value 1 441 F 1 Swim 6.07 2 5 G 2 Swim 5.92 3 26 D 3 Swim 6.47 4 445 E 5 Swim 6.72 5 32 F 6 Swim 6.42 6 2 H 7 Swim 6.03 > class(meltedTimes) [1] "data.frame"
...めんどくさいですし,
出力は欲しい形になっていますが, data.frameになっていてウザいです.
data.tableに移行しましょう.
data.tableの中で書くと, こんな感じです.
>times = times[ , list(Discipline=names(.SD), Time=unlist(.SD)), key=list(Position, StartingPosition, StartingTime, Age, Category)] > times Position StartingPosition StartingTime Age Category Discipline Time 1: 1 441 08:44:45 32 F Swim 00:06:04 2: 1 441 08:44:45 32 F Cycle 00:36:46 3: 1 441 08:44:45 32 F Run 00:19:11 4: 1 441 08:44:45 32 F Total 01:02:01 5: 2 5 08:46:00 35 G Swim 00:05:55 --- 1568: 392 46 08:56:15 42 H Total 03:29:02 1569: 393 8 08:46:45 35 G Swim 1570: 393 8 08:46:45 35 G Cycle 1571: 393 8 08:46:45 35 G Run 1572: 393 8 08:46:45 35 G Total 03:49:43
残す列名をkeyに指定すれば, 残りの列をmeltしてくれます.
.SDという変数がよく分かりませんが, これはkeyに指定しなかった列が勝手に入っているらしいです.
出力もdata.tableなので扱いやすいです.
追記: meltでmelt的な処理
dplyr特有のキモい記法である %.% を使ってmeltに流せることが分かりました.
r - reshape2: multiple results of aggregation function? - Stack Overflow
> time_melted = time %.% select(Position, Swim, Cycle, Run) %.% melt('Position') > head(time_melted) Position variable value 1 1 Swim 00:06:04 2 2 Swim 00:05:55 3 3 Swim 00:06:28 4 4 Swim 5 5 Swim 00:06:43 6 6 Swim 00:06:25
%.%でmelt関数にパイプして, 引数をIDとして扱ってくれるみたいです.
今回は, Positionをidとして, Swim, Cycle, Runの列をmeltしてくれました.
ただ, 出力はdataframeになるので, 注意が必要になる場合があります.
大きなデータを呼び出すと死にます.