さて、昨日は箱ひげ図を用いて色の調整方法を紹介しました。今日はカテゴリーごとに図を分割する方法を紹介します。
縦長データと横長データ
データの形状には横長と縦長の二種類が存在し、特にggplotでは縦長データが重宝されます。横長データというのは各列が別々のカテゴリーの値を格納している形状で、irisはまさに横長データです。もっとも直感的な表示方法だと思います。
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
これに対して縦長データというのは、特定の列群に対しその上の階層に位置する新たなカテゴリーを定義し、テーブルの列を圧縮したものです。例えば上のirisの例ではSepal.Length, Sepal.Width, Petal.Length, Petal.Widthの4つのカテゴリーをPhenotypeという1つのカテゴリーでまとめることで、次のように書き換えることができます。
Species | Phenotype | value |
setosa | Sepal.Length | 5.1 |
setosa | Sepal.Width | 3.5 |
setosa | Petal.Length | 1.4 |
setosa | Petal.Width | 0.2 |
setosa | Sepal.Length | 4.9 |
setosa | Sepal.Width | 3 |
図のカテゴリーごとの分割
以上のようにデータを縦長化することで、ggplotに異なるカテゴリーのデータを一度に渡せるようになり、図の分割が可能になります。
まずはirisのデータを縦長変換してみましょう。かつてはreshape2, gatherなどの関数で変換できたのですが、最近のアップデートでtidyrというパッケージのpivot_longerという関数に変わったようです。
data.iris <- iris
library(tidyr)
iris.long <- pivot_longer(data.iris,colnames(data.iris)[1:4],names_to = "Phenotype")
第一引数に横長のデータを与え、第二引数でひとまとめにしたいカテゴリーの列名を指定します。ここの指定の仕方はある程度自由度があるようで、適当に投げても意外と思ったように動いてくれます。もっと複雑な縦長化も可能なので、必要あればググってみましょう。
それでは各種(setosa, versicolor, virginica)について各カテゴリーの値の分布をバイオリンプロットを用いて比較してみましょう。facet_grid関数に分けたいカテゴリーが格納された列を指定するだけです。
library(ggthemes)
library(ggplot2)
g <- ggplot(iris.long,aes(x=Species,y=value))+
theme_base()+
geom_violin(aes(fill=Species))+
geom_boxplot(width=0.1)+
facet_grid(. ~ Phenotype)
ggsave("fig/1206_1.jpeg",g,width = 30,height = 15,units="cm")

このように、複数のカテゴリーの値を一つの図にすっきりとまとめられるようになりました(中央値を入れたかったのでboxplotを上書き)。
注意点として、同一の軸で複数のカテゴリーを列挙する手法なので数値が同じ基準で測定されていなければなりません。例えば、体重(kg)と身長(cm)を一つのカテゴリー「体型」としてまとめることはもちろん技術的には可能ですが、軸を統合してプロットするのはナンセンスです。そういう意味ではこのプロットに関しても値を標準化したりしたほうが良かったかもしれません。
また、データの分割と直接は関係ないですが90度回転させてプロットすることも可能です。
g <- ggplot(iris.long,aes(x=Species,y=value))+
theme_base()+
geom_violin(aes(fill=Species))+
geom_boxplot(width=0.1)+
facet_grid(Phenotype ~ .)+
coord_flip()
ggsave("fig/1206_2.jpeg",g,width = 20,height = 15,units="cm")

今回は種名が長いので、このように横向きにプロットしたほうが読みやすいかなと思います。
ちなみにカテゴリー列が2つあるとき、それぞれのカテゴリーの組み合わせを列挙して表示することも可能です。今回の例ではいまいちしっくりきませんが、SpeciesとPhenotypeの各要素の組み合わせのvalueが以下のスクリプトでプロット可能です。
g <- ggplot(iris.long,aes(x=Species,y=value))+
theme_base()+
geom_violin(aes(fill=Species))+
geom_boxplot(width=0.2)+
facet_grid(Species ~ Phenotype)+
coord_flip()
ggsave("fig/1206_3.jpeg",g,width = 40,height = 15,units="cm")

最後の例は今回のデータでは微妙でしたが、同種のデータを列挙する際は軸がまとまっていたほうが明快なのでぜひ活用していきましょう。それでは。