【reshape2,tidyr】 豆について考える(番外編)~溶けるの概念を見失った時のためのメモ~
前回の記事を書いていて、
2年前に
「reshape2::meltってなんだ。そもそもmeltってなんだ、溶けるってなんだ」
という、鳥はなぜ空を飛ぶの的な疑問に直面してたのを思い出したので、自分用メモ。
溶かすとは
当時釈然としてなかったのは、reshape2::meltを「えくせる的な行列入れ替え」と解釈していたことに端を発する。
◎えくせる的な行列入れ替え
◎reshape2::meltでの変換
・・・ちがうじゃんと。
思ってたのと違うじゃんと。
こんな変換誰が使うんだよと。 (cv.2年前わたし)
ということで、
そんな愚かな過去の自分に
使いどころと使い方と、tidyr::gatherとの微妙な表記の違いを捧げて、
反省してもらおうとおもいます。
題材
前回使った豆。
(引用:農林水産省/大豆関連データ集)
> mameused_xts<- mameused > mameused_xts$年<- mameused$年+1988 #西暦変換 > knitr::kable(mameused_xts) | 年|計 | みそ| しょうゆ| 豆腐.油揚| 納豆| 凍豆腐| 豆乳| 煮豆.惣菜| きな粉| その他| |----:|:-----|----:|--------:|---------:|----:|------:|----:|---------:|------:|------:| | 1997|1,019 | 165| 26| 494| 122| 30| 3| 33| 14| 132| | 1998|1,046 | 162| 26| 495| 128| 30| 4| 33| 16| 152| | 1999|1,017 | 166| 30| 492| 127| 29| 6| 33| 17| 117| | 2000|1,010 | 166| 30| 492| 122| 29| 7| 33| 17| 114| | 2001|1,015 | 149| 32| 492| 129| 29| 9| 33| 17| 125| | 2002|1,035 | 149| 35| 494| 141| 29| 11| 33| 17| 126| | 2003|1,034 | 138| 38| 494| 137| 30| 19| 33| 17| 128| | 2004|1,053 | 139| 37| 496| 139| 33| 29| 33| 18| 129| | 2005|1,052 | 141| 40| 494| 131| 33| 32| 33| 18| 130| | 2006|1,046 | 140| 40| 492| 130| 33| 30| 33| 18| 130| | 2007|1,045 | 139| 40| 497| 130| 30| 25| 33| 19| 132| | 2008|1,037 | 137| 39| 496| 129| 29| 25| 33| 19| 130| | 2009|993 | 131| 39| 490| 125| 27| 29| 33| 19| 100| | 2010|976 | 127| 39| 480| 123| 26| 32| 33| 19| 97| | 2011|950 | 126| 35| 465| 122| 24| 34| 31| 18| 95| | 2012|932 | 124| 33| 450| 123| 22| 40| 30| 17| 93| | 2013|936 | 123| 33| 454| 125| 20| 40| 30| 18| 93| | 2014|942 | 133| 33| 447| 125| 19| 43| 30| 18| 94|
使いどころ
こちらも前回の話だけど、
上記データの状態から積み上げ棒グラフを書きたいと思ったとき。
考えるのは、
・列名をFactor型にしたらできそう
・じゃあ縦型データじゃないとダメじゃない?
・でも年の列はそのままがよくない?
みたいなこと。
その処理をやるのに
reshape2::meltとかtidyr::gatherとかを使ってます。
もっとオサレな用途もあるにちがいない....例え出てこないけど...
いざ変換
前回やったのはこんな感じ。
id引数に年を指定して、それ以外を縦持ちに変換した。
> mameused_xts<-reshape2::melt(mameused_xts,id="年") #idを指定 > knitr::kable(head(subset(mameused_xts,mameused_xts$variable!="計") ,20)) | | 年|variable |value | |:--|----:|:--------|:-----| |19 | 1997|みそ |165 | |20 | 1998|みそ |162 | |21 | 1999|みそ |166 | |22 | 2000|みそ |166 | |23 | 2001|みそ |149 | |24 | 2002|みそ |149 | |25 | 2003|みそ |138 | |26 | 2004|みそ |139 | |27 | 2005|みそ |141 | |28 | 2006|みそ |140 | |29 | 2007|みそ |139 | |30 | 2008|みそ |137 | |31 | 2009|みそ |131 | |32 | 2010|みそ |127 | |33 | 2011|みそ |126 | |34 | 2012|みそ |124 | |35 | 2013|みそ |123 | |36 | 2014|みそ |133 | |37 | 1997|しょうゆ |26 | |38 | 1998|しょうゆ |26 |
ここから何パターンかやる。
idを明示的に指定しない
> #idを明示的に指定しない(計が使われる) > mameused_2<-reshape2::melt(mameused_xts) Using 計 as id variables > knitr::kable(head(mameused_2,20)) |計 |variable | value| |:-----|:--------|-----:| |1,019 |年 | 1997| |1,046 |年 | 1998| |1,017 |年 | 1999| |1,010 |年 | 2000| |1,015 |年 | 2001| |1,035 |年 | 2002| |1,034 |年 | 2003| |1,053 |年 | 2004| |1,052 |年 | 2005| |1,046 |年 | 2006| |1,045 |年 | 2007| |1,037 |年 | 2008| |993 |年 | 2009| |976 |年 | 2010| |950 |年 | 2011| |932 |年 | 2012| |936 |年 | 2013| |942 |年 | 2014| |1,019 |みそ | 165| |1,046 |みそ | 162|
年まで容赦なく溶かされる。これは何を基準にidを選んでるんだろう。
複数のidを指定
> mameused_2<-reshape2::melt(mameused_xts,id=c("年","計")) #idを複数指定 > knitr::kable(head(mameused_2,20)) | 年|計 |variable | value| |----:|:-----|:--------|-----:| | 1997|1,019 |みそ | 165| | 1998|1,046 |みそ | 162| | 1999|1,017 |みそ | 166| | 2000|1,010 |みそ | 166| | 2001|1,015 |みそ | 149| | 2002|1,035 |みそ | 149| | 2003|1,034 |みそ | 138| | 2004|1,053 |みそ | 139| | 2005|1,052 |みそ | 141| | 2006|1,046 |みそ | 140| | 2007|1,045 |みそ | 139| | 2008|1,037 |みそ | 137| | 2009|993 |みそ | 131| | 2010|976 |みそ | 127| | 2011|950 |みそ | 126| | 2012|932 |みそ | 124| | 2013|936 |みそ | 123| | 2014|942 |みそ | 133| | 1997|1,019 |しょうゆ | 26| | 1998|1,046 |しょうゆ | 26|
年と計の列をそのままに変換できる。
時代はtidyr::gatherらしい
meltを長々と語ってるけど、
reshape2パッケージの進化版の時代に突入してしまっているので、
そちらについてもやる。
id一つ指定の時と同じ変換
> mameused_2<-tidyr::gather(mameused_xts,key=variable,value=value,-年) > knitr::kable(head(mameused_2,20)) | 年|variable |value | |----:|:--------|:-----| | 1997|計 |1,019 | | 1998|計 |1,046 | | 1999|計 |1,017 | | 2000|計 |1,010 | | 2001|計 |1,015 | | 2002|計 |1,035 | | 2003|計 |1,034 | | 2004|計 |1,053 | | 2005|計 |1,052 | | 2006|計 |1,046 | | 2007|計 |1,045 | | 2008|計 |1,037 | | 2009|計 |993 | | 2010|計 |976 | | 2011|計 |950 | | 2012|計 |932 | | 2013|計 |936 | | 2014|計 |942 | | 1997|みそ |165 | | 1998|みそ |162 |
引数がびみょうに違う。
meltがidに「残したい列(名)を指定」だったのに
gatherは「溶かしたい列名を指定」なので、残したい列は「-」マイナスを付けて除外指定をする。
keyとvalueには変換後の列名を指定する。
idの複数指定
> mameused_2<-tidyr::gather(mameused,key,value,-年,-計) #溶かさないものはマイナス指定 > knitr::kable(head(mameused_2,20)) | 年|計 |key | value| |--:|:-----|:--------|-----:| | 9|1,019 |みそ | 165| | 10|1,046 |みそ | 162| | 11|1,017 |みそ | 166| | 12|1,010 |みそ | 166| | 13|1,015 |みそ | 149| | 14|1,035 |みそ | 149| | 15|1,034 |みそ | 138| | 16|1,053 |みそ | 139| | 17|1,052 |みそ | 141| | 18|1,046 |みそ | 140| | 19|1,045 |みそ | 139| | 20|1,037 |みそ | 137| | 21|993 |みそ | 131| | 22|976 |みそ | 127| | 23|950 |みそ | 126| | 24|932 |みそ | 124| | 25|936 |みそ | 123| | 26|942 |みそ | 133| | 9|1,019 |しょうゆ | 26| | 10|1,046 |しょうゆ | 26|
溶かしたくない列を複数指定する時はカンマで区切っちゃってOK。
meltでid=c("年","計")ってした時と同じ結果になる。
おまけ
上記でやってないけど、
data引数はパイプで渡しちゃうのが正なのでしょう。
> mameused_xts %>% + tidyr::gather(key,value,-年)->mameused_2 > knitr::kable(head(mameused_2,20)) | 年|key |value | |----:|:----|:-----| | 1997|計 |1,019 | | 1998|計 |1,046 | | 1999|計 |1,017 | | 2000|計 |1,010 | | 2001|計 |1,015 | | 2002|計 |1,035 | | 2003|計 |1,034 | | 2004|計 |1,053 | | 2005|計 |1,052 | | 2006|計 |1,046 | | 2007|計 |1,045 | | 2008|計 |1,037 | | 2009|計 |993 | | 2010|計 |976 | | 2011|計 |950 | | 2012|計 |932 | | 2013|計 |936 | | 2014|計 |942 | | 1997|みそ |165 | | 1998|みそ |162 |
おわり
完全に備忘録。
もうすぐの誕生日、忘れっぱなしでいったら年取らないで済むかなあ