株式会社ホクソエムのブログ

R, Python, データ分析, 機械学習

ggplot2 で facet ごとのヒストグラムに平均値の線を引く

ggplot2 で facet ごとのヒストグラムに平均値の線を引きたい。

例えば次のような感じ。

f:id:hoxo_m:20181108192139p:plain

Rコミュニティの Slack である r-wakalang で聞いたところ、即回答がもらえただけでなく、いろいろなやり方を教わったのでメモしておく。 みなさんありがとう。

基本作図

まずはデータを準備する。 ここでは有名な iris データから数値カラム x と facet を作るためのカテゴリカル変数 group を持つデータフレームを作成する。

data(iris) # iris データの読み込み(通常は必要ない)

library(dplyr)

# データの作成
data <- iris %>% select(x = Sepal.Length, group = Species)
# データ内容の確認
head(data)
    x  group
1 5.1 setosa
2 4.9 setosa
3 4.7 setosa
4 4.6 setosa
5 5.0 setosa
6 5.4 setosa

このデータに対して、グループごとにヒストグラムを作成する。

library(ggplot2)
ggplot(data, aes(x)) + 
    geom_histogram() +
    facet_wrap(~group, ncol=1)

f:id:hoxo_m:20181108192206p:plain

この3つのヒストグラムに対して、それぞれのグループの平均値を表す垂直線を追加したいというのが今回の目的。

facet ごとの集計値の扱い

ggplot2 で facet ごとに集計値を扱う場合は、別データとして集計済みのデータを用意する。

例えば今回は平均値の垂直線を引きたいので、次のように平均値を計算したデータフレームを用意する。

data_summary <- data %>%
    group_by(group) %>%
    summarise(mean_x = mean(x))
data_summary
  group      mean_x
1 setosa       5.01
2 versicolor   5.94
3 virginica    6.59

この集計データを用いて平均値をグラフに書き込むことができる(ura_hoxom さん)。

ggplot(data, aes(x)) + 
    geom_histogram() +
    facet_wrap(~group, ncol=1) +
    geom_vline(data = data_summary, aes(xintercept = mean_x), color = "red")

f:id:hoxo_m:20181108192139p:plain

目的は達成された。

他の方法

他の方法も教えてもらった。 ggplot2 では集計データを用意しなくても、集計用の関数を渡すと自動的にデータ集計してくれるらしい。

例えば、次のようにグループごとに平均値を集計する関数を用意する。

mean_by_group = function(d) {
    d %>% group_by(group) %>% summarize(mean_x = mean(x))
}

集計済みデータの代わりに、これを ggplot2 に渡すことができる(heavywatal さん)。

ggplot(data, aes(x)) + 
    geom_histogram() +
    facet_wrap(~group, ncol=1) +
    geom_vline(data = mean_by_group, aes(xintercept = mean_x), color = "red")

f:id:hoxo_m:20181108192139p:plain

また、集計する関数については次のように簡潔に作成できる(yutannihilation さん)*1

mean_by_group = . %>% group_by(group) %>% summarize(mean_x = mean(x))

まとめ

というわけで、みなさんいろいろ教えてくださってありがとうございました。

R-wakalang への参加の仕方については次の資料を参考にしてください。

Enjoy!

*1:これは magrittr の機能らしい。https://github.com/tidyverse/magrittr#building-unary-functions 参照。