ggplotのfacet_grid(), facet_wrap()の使い方

Rでggplotを使ってグラフを作るときに, 比較したい対象が増えてくることがあると思います. 例えば, 散布図や棒グラフで, x, y軸に指定した値以外の要素で比較するときなどです. そんな時には, facet_gridや, facet_wrapを使うことで実現できます.

facet_grid()の使い方

ggplotを使うのが初めての方は, 良かったら「ggplotの使い方」を参考にしてください. このページでは, ggplotの関数の中でも, 特にfacet_grid()関数の使い方の流れを説明していくつもりです.

今回使用するデータセットはdiamondsです. このデータセットは, ggplot2のパッケージに入っているものなので, ggplot2のパッケージを読み込んだあとから使えるようになります. では, まずは散布図を作ってみます. x軸はcarat, y軸はpriceを指定します.

> library(ggplot2)
> str(diamonds)
'data.frame':   53940 obs. of  10 variables:
 $ carat  : num  0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
 $ cut    : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
 $ color  : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
 $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
 $ depth  : num  61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
 $ table  : num  55 61 65 58 58 57 57 55 61 61 ...
 $ price  : int  326 326 327 334 335 336 336 337 337 338 ...
 $ x      : num  3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
 $ y      : num  3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
 $ z      : num  2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...
> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point()
> ggsave("ggplot_facet1.png")
Saving 7 x 7 in image
            
ggplot_facet1.png

では, 実際に, facet_grid()を使ってみます. 書き方は, facet_grid(row ~ column)という形になります. row ~ columnrowcolumnには, それぞれデータフレームの要素の名前をいれます. その時, rowに入れた要素について行で区分けをし, columnに入れた要素について, 列で区分けをします. .(ドット)を入れると, どの要素でも区分けしないことを意味します.

例として, colorを使って, 列で区分けしてみます. あとfacet_grid()には関係ありませんが, 見栄えのために, clarityについて色分けをすることにします.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_grid(. ~ color)
> ggsave("ggplot_facet2.png")
Saving 7 x 7 in image
            
ggplot_facet2.png

列で区分けされました. 上のコードで, .colorを入れ替えれば, 区分けの方向を変えることができます.

では, つぎに, 行方向はcutで, 列方向はcolorで区分けしてみましょう.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_grid(cut ~ color)
> ggsave("ggplot_facet3.png")
Saving 7 x 7 in image
            
ggplot_facet3.png

また, 行や列に関して, 2つ以上の要素で区分けすることもできます.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_grid(. ~ color + cut)
> ggsave("ggplot_facet4.png")
Saving 7 x 7 in image
            
ggplot_facet4.png

ここまで分割すると, なんだかわけがわからないグラフになりますが, 上のラベルをよく見ると, 7(colorの種類)*5(cutの種類)=35個に区分けされていることがわかります.

区分けをしていくと, 全体に対するグラフがわからなくなってしまうことがあるので, 全体のグラフを付け加えることもできます. facet_grid()の引数にmargins=TRUEを加えます.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_grid(cut ~ color, margins=TRUE)
> ggsave("ggplot_facet5.png")
Saving 7 x 7 in image
            
ggplot_facet5.png

上の画像からわかるように, 区分けの種類に(all)が加わりました.

他にも指定できるオプションはあるようですが, 基本的にはこんな感じで使います.

facet_wrap()の使い方

facet_grid()は, 行と列それぞれに分ける要素を指定して, 行と列ごとに区分けしていました. facet_wrap()では, 要素を指定すると, 勝手にそれを2次元に区分けします. なんだか文字で書くとあまり伝わらなそうなので, 例を見て行きましょう.

ちなみに書き方は, facet_wrap(~ variables)になります. variablesの部分に, 区分けしたい要素をいれます.

では, データセットは引き続きdiamondsを使って, 区分けする要素は, colorにします.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_wrap(~ color)
> ggsave("ggplot_facet6.png")
Saving 7 x 7 in image
            
ggplot_facet6.png

2次元で区分けすると書いたのは, こういうことです. gridの時よりは縦長なグラフにならないので, バランスよく区分けできていると思います.

facet_wrap()では, 引数で, 行で分ける数または, 列で分ける数を指定できます. 例えば, 列を4行にしたいとすると,

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_wrap(~ color, ncol=4)
> ggsave("ggplot_facet7.png")
Saving 7 x 7 in image
            
ggplot_facet7.png

というように, ncolで指定することで実現できます. 行について区分けする数を指定したいときには, nrowを使って同様に指定します.

facet_grid()の時と同じように, 2要素以上指定することもできます.

> p <- ggplot(diamonds, aes(x=carat, y=price))
> p + geom_point(aes(colour=clarity)) + facet_wrap(~ color + cut)
> ggsave("ggplot_facet8.png")
Saving 7 x 7 in image
            
ggplot_facet8.png

こんな感じです. うまくfacet_grid()facet_wrap()を使い分けることで, より視認性の高いグラフをつくることができると思います.