reshape2でデータ整形
パッケージのサンプルを例に手を動かす。
まずはパッケージのロード&使うデータ(airquality)の確認。
このairqualityデータフレームは「ozone,solar.r,wind,temp,month,day」を列に持つデータフレームということ。
> library(reshape2) > names(airquality) <- tolower(names(airquality)) > str(airquality) 'data.frame': 153 obs. of 6 variables: $ ozone : int 41 36 12 18 NA 28 23 19 8 NA ... $ solar.r: int 190 118 149 313 NA NA 299 99 19 194 ... $ wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ... $ temp : int 67 72 74 62 56 66 65 59 61 69 ... $ month : int 5 5 5 5 5 5 5 5 5 5 ... $ day : int 1 2 3 4 5 6 7 8 9 10 ... > head(airquality) ozone solar.r wind temp month day 1 41 190 7.4 67 5 1 2 36 118 8.0 72 5 2 3 12 149 12.6 74 5 3 4 18 313 11.5 62 5 4 5 NA NA 14.3 56 5 5 6 28 NA 14.9 66 5 6
これをmelt関数でmonthとdayに対してその名の通り"融かす(melt)"と、
それ以外の列(ozone,solar.r,wind,temp)が全てvariable列に格納され、対応する値がvalue列に入るようになる。
つまりmonthとdayを重複ありのキーだと思って対応する「その他の列(要素)・その列の値」というように分解するということ。
> aq.m <- melt(airquality, id=c("month", "day"), na.rm=TRUE) > head(aq.m) month day variable value 1 5 1 ozone 41 2 5 2 ozone 36 3 5 3 ozone 12 4 5 4 ozone 18 6 5 6 ozone 28 7 5 7 ozone 23 > str(aq.m) 'data.frame': 568 obs. of 4 variables: $ month : int 5 5 5 5 5 5 5 5 5 5 ... $ day : int 1 2 3 4 6 7 8 9 11 12 ... $ variable: Factor w/ 4 levels "ozone","solar.r",..: 1 1 1 1 1 1 1 1 1 1 ... $ value : num 41 36 12 18 28 23 19 8 7 16 ...
このmeltした状態で(a|d)cast関数を適用すると「○○毎に××した量」を簡単に計算することができる。
ここでは「月ごとに平均した量」をそれぞれの変数(ozone,solar.r,wind,temp)で計算してみる。
(a|d)castはそれぞれ「列名として変数を使うor第一列に変数を入れる」の違いに対応しており、
「xxx~yyy」の箇所は出力データの縦横の違いに対応しているだけなので、あまり本質的ではなさそう。
> dcast(aq.m, month ~ variable, mean) month ozone solar.r wind temp 1 5 23.61538 181.2963 11.622581 65.54839 2 6 29.44444 190.1667 10.266667 79.10000 3 7 59.11538 216.4839 8.941935 83.90323 4 8 59.96154 171.8571 8.793548 83.96774 5 9 31.44828 167.4333 10.180000 76.90000 > dcast(aq.m, variable ~ month , mean) variable 5 6 7 8 9 1 ozone 23.61538 29.44444 59.115385 59.961538 31.44828 2 solar.r 181.29630 190.16667 216.483871 171.857143 167.43333 3 wind 11.62258 10.26667 8.941935 8.793548 10.18000 4 temp 65.54839 79.10000 83.903226 83.967742 76.90000 > acast(aq.m, month ~ variable, mean) ozone solar.r wind temp 5 23.61538 181.2963 11.622581 65.54839 6 29.44444 190.1667 10.266667 79.10000 7 59.11538 216.4839 8.941935 83.90323 8 59.96154 171.8571 8.793548 83.96774 9 31.44828 167.4333 10.180000 76.90000 > acast(aq.m, variable ~ month , mean) 5 6 7 8 9 ozone 23.61538 29.44444 59.115385 59.961538 31.44828 solar.r 181.29630 190.16667 216.483871 171.857143 167.43333 wind 11.62258 10.26667 8.941935 8.793548 10.18000 temp 65.54839 79.10000 83.903226 83.967742 76.90000
さらにplyrパッケージを合わせて導入していればsubsetを使って特定の列(variable)だけを抽出することもできる。
> library(plyr) > dcast(aq.m, month~variable, mean,subset=.(variable=="ozone")) month ozone 1 5 23.61538 2 6 29.44444 3 7 59.11538 4 8 59.96154 5 9 31.44828