ggplot2のgeom_boxplotについて備忘録
ggplot2の箱ひげ図を描く関数の備忘録。
geom_boxplot
penguinsデータで箱ひげ図を描く。
library(tidyverse) library(palmerpenguins) data(package = 'palmerpenguins') df <- penguins df %>% ggplot2::ggplot(ggplot2::aes(x = species, y = bill_length_mm)) + ggplot2::geom_boxplot()
A box and whiskers plot (in the style of Tukey) — geom_boxplot • ggplot2
平均の線を引く
箱の真ん中の線は平均値ではなく中央値。四分位で分けるのが箱ひげ図なので、箱の上が第3四分位、下が第1四分位、真ん中が第2四分位でつまり中央値になる。
それでも平均値を描画したい場合はstat_summaryを使用する。(stat_summaryあんまり調べてないので怪しい。)
df %>% ggplot2::ggplot(ggplot2::aes(x = species, y = bill_length_mm)) + ggplot2::geom_boxplot() + ggplot2::stat_summary(fun = mean, geom = "errorbar", aes(ymax = ..y.., ymin = ..y..), width = 0.75, size = 1, linetype = "dotted")
r - How do I plot the mean instead of the median with geom_boxplot? - Stack Overflow
ひげの先端を最大値最小値にする
ひげの先端が何を表しているのかは決まっている訳ではないらしい。
geom_boxplotはデフォルトでは箱の端からIQRの1.5倍内の最小最大がひげの先端になる。
ひげより先にある点は外れ値と解釈される。IQRとはInterquartile Rangeの略で、第3四分位数から第1四分位数を引いたもの。
四分位範囲 | 統計用語集 | 統計WEB
一方で、ひげの先端を最大値最小値として説明している場合もある。
4-2. 箱ひげ図の見方 | 統計学の時間 | 統計WEB
geom_boxplotのひげの先端を最大値最小値にするには、ひげの長さを調整するcoefという引数に値を設定する。coefに設定した数値がIQRに掛けられた結果がひげの長さになる。デフォルトは1.5。
適当に大きな数値を設定すれば最大値最小値が先端になるが、なんか違う気がする……。
df %>% ggplot2::ggplot(ggplot2::aes(x = species, y = bill_length_mm)) + ggplot2::geom_boxplot(coef = 1000)
箱の並び替え
並び替えはreorderを使う。箱ひげ図の真ん中の線である中央値で並び替える場合が多いはず。
df %>% dplyr::filter(!is.na(bill_length_mm)) %>% ggplot2::ggplot(ggplot2::aes(x = reorder(x = species, X = bill_length_mm, FUN = median), y = bill_length_mm)) + ggplot2::geom_boxplot()
ここではdplyr::filterでNAを除外しているが、除外しないとこうなる。
df %>% ggplot2::ggplot(ggplot2::aes(x = reorder(x = species, X = bill_length_mm, FUN = median), y = bill_length_mm)) + ggplot2::geom_boxplot()
並び替えられていない。これはreorderのmedianがNAを除外していないため、集計結果がNAになってしまって並び替えが機能していない。
先のようにdplyr::filterで除外するか、もしくはreorderが...(dot-dot-dot)でFUNに引数を渡せるのでna.rm=TRUEを設定する。
… optional: extra arguments supplied to FUN
reorder.default function - RDocumentation
df %>% ggplot2::ggplot(ggplot2::aes(x = reorder(x = species, X = bill_length_mm, FUN = median, na.rm = TRUE), y = bill_length_mm)) + ggplot2::geom_boxplot()