J

data.frame を ggplot2 用に加工する

f:id:joker1110:20120217070139p:image:w360

背景

ggplot2でデータを図示するとき,data.frame()の形にしておくことが必須!
でも,巷に存在するデータは必ずしも適したdata.frame()の形になっていない.
このような統計データが巷には多く存在する.横軸に時間,縦軸にカテゴリである.

> sdata <- read.csv("reshape_data.csv",header=T)
> sdata
   X            X2003        X2004          X2005          X2006          X2007          X2008
1 A 0.639303353 0.1606200 0.49761181 0.05821738 0.28906559 0.86778986
2 B 0.151501818 0.9834539 0.73344139 0.89570543 0.40995754 0.02346937
3 C 0.003360582 0.8289247 0.84555681 0.88112286 0.03419304 0.59529404
4 D 0.923997222 0.5709377 0.01070927 0.34586471 0.95764872 0.89591526

目的

ggplot2に適した形にするには,時間列を作り,そこに時間値を書き込みたいわけだ.
つまり,こんな感じ

   name  time                    X id
1       A 2003 0.639303353  1
2       B 2003 0.151501818  2
3       C 2003 0.003360582  3
4       D 2003 0.923997222  4
1       A 2004 0.160620002  1
2       B 2004 0.983453932  2
3       C 2004 0.828924747  3
4       D 2004 0.570937680  4
1       A 2005 0.497611813  1
2       B 2005 0.733441391  2
3       C 2005 0.845556813  3

できる限り簡単に,ggplot2に適したdata.frame()の形にしたい.

手段

reshape()を利用する。(追記にmelt.data.frameを利用した簡単な方法があります。推奨。)

実験

まず,時系列を表す列名を「キー.数字」または「キー.文字列」のようにキーで表す.たとえば,

> sname <- c("X.2003","X.2004","X.2005","X.2006","X.2007","X.2008")

のように時間で表したい文字列を作成しておく.
次に,データの列名を変更.

> names(sdata) <- c("name",sname)
> sdata
  name      X.2003    X.2004     X.2005     X.2006     X.2007     X.2008
1    A 0.639303353 0.1606200 0.49761181 0.05821738 0.28906559 0.86778986
2    B 0.151501818 0.9834539 0.73344139 0.89570543 0.40995754 0.02346937
3    C 0.003360582 0.8289247 0.84555681 0.88112286 0.03419304 0.59529404
4    D 0.923997222 0.5709377 0.01070927 0.34586471 0.95764872 0.89591526

これで準備はできた.あとはreshape()するだけ.

> sdata <- reshape(sdata, direction="long", varying=sname)
> sdata
       name time           X id
1.2003    A 2003 0.639303353  1
2.2003    B 2003 0.151501818  2
3.2003    C 2003 0.003360582  3
4.2003    D 2003 0.923997222  4
1.2004    A 2004 0.160620002  1
2.2004    B 2004 0.983453932  2
3.2004    C 2004 0.828924747  3
4.2004    D 2004 0.570937680  4
1.2005    A 2005 0.497611813  1

完成!列名timeに時間が入っている.ただidという列が付加されちゃうのはなぜ??

結論

reshape()することで,横長のデータ(横軸に時系列)を縦長のデータ(時間を列に収納したもの)に簡単に変更可能.
ただ,もとの列名にidという名前を入れるとエラーになるようです.

追記

もっと簡単な方法があった.melt.data.frame()を利用する方法.

> sdata <- read.csv("reshape_data.csv",header=T)
> sdata
   X            X2003        X2004          X2005          X2006          X2007          X2008
1 A 0.639303353 0.1606200 0.49761181 0.05821738 0.28906559 0.86778986
2 B 0.151501818 0.9834539 0.73344139 0.89570543 0.40995754 0.02346937
3 C 0.003360582 0.8289247 0.84555681 0.88112286 0.03419304 0.59529404
4 D 0.923997222 0.5709377 0.01070927 0.34586471 0.95764872 0.89591526

に対して

> sdata <- melt.data.frame(sdata,id.vars="X",variable_name="year")
> sdata
   X  year       value
1  A X2003 0.639303353
2  B X2003 0.151501818
3  C X2003 0.003360582
4  D X2003 0.923997222
5  A X2004 0.160620002
6  B X2004 0.983453932
7  C X2004 0.828924747
8  D X2004 0.570937680
9  A X2005 0.497611813
10 B X2005 0.733441391
11 C X2005 0.845556813
12 D X2005 0.010709274
13 A X2006 0.058217382
14 B X2006 0.895705435
15 C X2006 0.881122858
16 D X2006 0.345864708
17 A X2007 0.289065585
18 B X2007 0.409957539
19 C X2007 0.034193039
20 D X2007 0.957648725
21 A X2008 0.867789855
22 B X2008 0.023469369
23 C X2008 0.595294041
24 D X2008 0.895915255

一行で書けた.

統計データをggplot2で可視化するときの色

背景

統計的にデータを扱う場合,データの種類は大きく分けて次の3つ.

  • 順次的(sequential)
  • 定性的(qualitative)
  • 発散的(diverging)

これらを可視化するとき,色分けすると便利.ただし,色使いには注意が必要

目的

ggplot2で可視化するとき,データの種類によって色を使い分ける方法を模索

方法

ggplot2で色を分けて可視化するときの手段として

  1. ggplot2のscale_gradient, scale_gradient2, scale_gradientn を利用
  2. RパッケージのRColorBrewerを利用
  3. 自分で定義

の3つが考えられる.
ここで問題.適切な色とは何か?
W. S. Cleveland の The Elements of Graphing Data によれば,CMYKをベースに考えて次のパタンがオススメらしい

順次的データ
cyan から magenta への濃淡で表す
定性的データ
cyan,magenta,green,orange,light blue の5色で表す

さて,cyanやmagentaの色一覧は次の通り

(c,m,y,k) #rrggbb 色名
(1,0,0,0) #00a0e9 cyan
(0,1,0,0) #e4007f magenta
(1,0,1,0) #009944 green
(0,0.5,1,0) #f39800 orange
(1,0.5,0,0) #0068b7 light blue

これらを利用して,ggplot2で色を分けてみる.

実験

まずは色の定義

cCyan <- "#00a0e9"
cMagenta <- "#e4007f"
cGreen <- "#009944"
cOrange <- "#f39800"
cLightBlue <- "#0068b7"
qcolours <- c(cCyan,cMagenta,cGreen,cOrange,cLightBlue)
順次的データ

data=mtcarsを利用する.まずはそのままプロット(背景は白に設定).

p <- ggplot(mtcars, aes(mpg, wt)) 
p <- p + geom_point(aes(colour=cyl),size=3)
p <- p + theme_bw(24)
p

f:id:joker1110:20111202215040p:image:w360
次に,Clevelandの色設定を適用

p + scale_colour_gradient(low=cCyan,high=cMagenta)

f:id:joker1110:20111202215038p:image:w360
見やすくなったかな.
また他の方法として,奥村先生の色設定を適用する

p + scale_colour_gradient(low=cLightBlue,high=cOrange)

f:id:joker1110:20111202215037p:image:w360
となり,さらに見やすくなった.
個人的には,奥村先生の方法が最も良い.

定性的データ

data=diamondsを小さくしたdsmallを利用する.まずはそのままプロット.

dsmall <- diamonds[sample(nrow(diamonds), 100), ] 
p <- ggplot(dsmall, aes(carat, price))
p <- p + geom_point(aes(colour=cut),size=3)
p <- p + theme_bw(24)
p

f:id:joker1110:20111202215036p:image:w360
これにClevelandの方法を適用する

p + scale_colour_manual(aes(cut), value = qcolours)

f:id:joker1110:20111202215034p:image:w360
メリハリが明確で良い感じ.

結論

Clevelandの方法のように色分けを工夫することで,可視化データの情報がよりハッキリと見て取れる!

参考文献