reshape関数とtidyrの関係

ひとりアドベントカレンダー16日目。
こういうデータセットがあったとする。

> (smp <- data.frame(ID=rep(1:3, 2),
+                   BMI=rep(c(21,26),3),
+                   sbp=rep(c(150,120),3),
+                   nendo=rep(2008:2009, 3)
+                   )
+ )
  ID BMI sbp nendo
1  1  21 150  2008
2  2  26 120  2009
3  3  21 150  2008
4  1  26 120  2009
5  2  21 150  2008
6  3  26 120  2009

これをnendo情報をBMIとsbpに加えた形で横方向に展開する時、組み込みのstatsパッケージの関数ならreshape関数を使う。

> reshape(smp, idvar="ID", timevar="nendo", direction="wide")
  ID BMI.2008 sbp.2008 BMI.2009 sbp.2009
1  1       21      150       26      120
2  2       21      150       26      120
3  3       21      150       26      120

これと同じことをtidyrパッケージを使ってやろうとすると、gather→unite→spreadという流れでやる。

> library("tidyr")
> smp %>% gather(var, value, -ID, -nendo) %>% 
+   unite(var_nendo, var, nendo) %>% 
+   spread(var_nendo, value)
  ID BMI_2008 BMI_2009 sbp_2008 sbp_2009
1  1       21       26      150      120
2  2       21       26      150      120
3  3       21       26      150      120

めんどくさいのでreshape関数一択でいいかなと思うも、dplyrパッケージの関数を適用してtbl形式になっている場合、reshapeはバグる。

library("dplyr")
reshape(as.tbl(smp), idvar="ID", timevar="nendo", direction="wide")
Source: local data frame [3 x 3]

  ID BMI.2008:2009 sbp.2008:2009
1  1            NA            NA
2  2            NA            NA
3  3            NA            NA

以前、この件をissueで上げたがas.data.frame使えやって返答がきたので対応する気はないらしい。
dplyrとtidyrはどちらもHadley Wickhamが開発しているので当然相性はいい。
だからas.data.frameを使うのがなんだかダサいなと思うときはtidyrを使うといい。

> as.tbl(smp) %>% gather(var, value, -ID, -nendo) %>% unite(var_nendo, var, nendo) %>% spread(var_nendo, value)
Source: local data frame [3 x 5]

  ID BMI_2008 BMI_2009 sbp_2008 sbp_2009
1  1       21       26      150      120
2  2       21       26      150      120
3  3       21       26      150      120

そんなHadley Wickhamが書いたAdvanced Rがもうすぐ翻訳されて出版されるよ!!!
みんなも決断的に買おう!!!

R言語徹底解説

R言語徹底解説