【R】箱ひげ図はすべてこれにしてくれ【生物学】

生物学に限らず、様々な分野の科学論文において、私たちは**箱ひげ図**を目にすると思います。箱ひげ図は主に**群間におけるデータの分布を可視化**するために用いられますが、いくつかの致命的な欠点を抱えています。そのため、箱ひげ図を使う際は、特にデータの分布について注意を払う必要があります。しかしながら、非意図的なのかあえてなのか分かりませんが、箱ひげ図を使った不適切な可視化をしている論文が次から次へと出版されています。ここでは、以下に示す箱ひげ図の欠点を補ったプロット方法を紹介します。不適切な箱ひげ図がなくなりますように・・・！

よりよい方法があればご教示いただければ幸いです。

### 環境

```
R version 4.3.1
ggplot2 3.4.2
```
---

### 箱ひげ図の主要な欠点

- **サンプルサイズが分からない**
- **データの分布に関する情報が失われる**


詳しくは以下のサイトを参照してください。
>[The Boxplot and its pitfalls（箱ひげ図とその落とし穴）](https://www.data-to-viz.com/caveat/boxplot.html "外部リンクに飛びます")



---

### ベーシックな箱ひげ図
irisデータセットを使って、まずは普通にプロットしてみます。

```R:boxplot
library(tidyverse)
library(viridis)

plot1 <- ggplot(iris, aes(x = Species, y = Sepal.Length))+
  geom_boxplot(width = 0.5, color = "black", alpha=0.7)+
  theme_bw(base_size = 12)+
  labs(title="Sepal.Length")+
  theme(legend.position="none")
```

![plot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458298/fb2b58c7-17a8-7e0b-bd15-8dbacf16e419.png)
シンプルできれいな図ですが、サンプル数やデータの分布の情報は完全に欠落しています。そういった情報も残した可視化をしたいところです。

---

### 今回提案する箱ひげ図
を描くコードがこちら。

```R:plot2
plot2 <- ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species))+
  geom_violin(alpha = 0.6)+
  scale_fill_viridis(option = "D", discrete = T)+
  geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
               position = position_nudge(-0.05))+
  geom_boxplot(width = 0.1, color = "black", alpha=0.7,
               position = position_nudge(+0.05))+
  theme_bw(base_size = 10)+
  labs(title="Sepal.Length")+
  #labs(x = NULL, y = NULL)+
  theme(legend.position="none")
```
![plot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458298/063d53c6-fa8c-d979-08ce-82959bd74184.png)
サンプルサイズとデータの分布の情報が失われていない＆それらが視覚的に分かりやすい理想的な図！

#### サンプルサイズの表示を追加してみる
どうせならサンプル数がいくつなのか示せれば、さらに親切ですね。

```R:サンプルサイズの取得
samplesize <- iris %>% 
  group_by(Species) %>% 
  tally()
```
まずはサンプルサイズを取得します。

```R:plot3
plot3 <- ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species))+
  geom_violin(alpha = 0.6)+
  scale_fill_viridis(option = "D", discrete = "True")+
  geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
               binwidth = 0.1, position = position_nudge(-0.05))+
  geom_boxplot(width = 0.1, color = "black", alpha=0.7,
               position = position_nudge(+0.05))+
  theme_bw(base_size = 12)+
  labs(title="Sepal.Length")+
  #labs(x = NULL, y = NULL)+
  theme(legend.position="none")+
  geom_text(data = samplesize,
            aes(Species, Inf, label = paste0("n = ", n)),
            vjust = 1.25, size=3, color="black") #サンプルサイズの書き込み
```
今回は図の上の方にのせてみます。
![plot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458298/82bb1d4b-bfa5-061e-21c8-12a08610e320.png)

ちょっときついですが、スペースを調整すればいい感じになりそう。

X軸にサンプル数を表示したい場合は以下を参照してください。
[Violin plot with included boxplot and sample size in ggplot2](https://r-graph-gallery.com/violin_and_boxplot_ggplot2.html)

---
### おまけ

[The R Graph Gallery](https://r-graph-gallery.com/89-box-and-scatter-plot-with-ggplot2.html)にある箱ひげ図が苦手そうなデータでも図示してみます。

```R:data
data <- data.frame(
  name=c(rep("A",500), rep("B",500), rep("B",500), rep("C",20), rep('D', 100)),
  value=c(rnorm(500, 10, 5), rnorm(500, 13, 1), rnorm(500, 18, 1), rnorm(20, 25, 4), rnorm(100, 12, 1))
)
# 引用: https://r-graph-gallery.com/89-box-and-scatter-plot-with-ggplot2.html
```

```R:plot4
plot4 <- ggplot(data, aes(x = name, y = value, fill = name))+
  geom_violin(alpha = 0.6)+
  scale_fill_viridis(option = "D", discrete = "True")+
  geom_dotplot(binaxis = "y", stackdir = "down", dotsize = 0.5,
               binwidth = 0.25, position = position_nudge(-0.05))+
  geom_boxplot(width = 0.1, color = "black", alpha=0.7,
               position = position_nudge(+0.05))+
  theme_bw(base_size = 12)+
  labs(title="data")+
  theme(legend.position="none")
```

![plot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458298/c18adf47-2b14-7cdb-8514-83043efdb2f4.png)
オオン・・・。
サンプル数が多いときはドットプロットよりジッタープロットの方がいいかもしれませんね。

---

### 最後に
当たり前ですが、今回紹介したプロットはあらゆるデータに適合するわけではありません。データの分布や数によって、最適な可視化方法を探索していきましょう！