見出し画像

ggplot2: 複数のデータセットの棒グラフを1枚の図にまとめる方法

複数のデータセットがあった場合、データセットごとに色を変えて区別することで、棒グラフを1つの図にまとめる方法の紹介です。

具体的には、下図のような棒グラフです。2つのシーズン (season) ごとにデータセットがあり、シーズンを色で区別することで、1枚の図にまとめています。

2つのデータセットをまとめた棒グラフ

データセットごとに異なる色で棒グラフを作成

ggplot2 において、データセットごとに塗り分けるコードは単純です。データセット1つの場合と、ほとんど変わりません。

g <- ggplot(plot_data, aes(percentage, buki, fill = season)) +
  geom_col(position = "dodge")

g + theme(text = element_text(family = "HiraKakuProN-W3")) +
  scale_fill_discrete(breaks = c("drizzle2023", "chill2023")) +
  labs(x = "使用率(%)", y = "",
       title = "ブキ使用率の比較(上位20, chill2023)", subtitle = "ナワバリ Drizzle 2023 - Chill 2023")

まず、ggplot() に指定する aes() の中で、 「fill = season」と、season の値で塗ることを指定します。続いて、 geom_col() の引数に 「position = "dodge"」を指定するだけです。

* scale_fill_discrete(breaks = c("drizzle2023", "chill2023")) の部分は、凡例のデータセットの並びを指定しています。この指定がないとアルファベット順になるため、chill2023 が上に来てしまいます。

大変なのはプロット用データの整形

このような棒グラフを作成する場合、大変なのは、データのテーブルを整形してプロット用のデータを準備する作業です。

上記でプロット用データとして使用した plot_data は、下記のようなテーブルになっています。テーブルが2つあるわけではなく、 season の列の値で区別するように、join()gather() を使ってまとめる必要があります。

> plot_data
# A tibble: 40 × 4
   weapon         buki                 season      percentage
   <chr>          <fct>                <chr>            <dbl>
 1 fincent_hue    フィンセント・ヒュー drizzle2023      NA
 2 fincent_hue    フィンセント・ヒュー chill2023         1.45
 3 variableroller ヴァリアブルローラー drizzle2023       1.70
 4 variableroller ヴァリアブルローラー chill2023         1.45
 5 sharp          シャープマーカー     drizzle2023       2.15
 6 sharp          シャープマーカー     chill2023         1.66
 7 splatroller    スプラローラー       drizzle2023       1.54
 8 splatroller    スプラローラー       chill2023         1.67
 9 pablo          パブロ               drizzle2023       1.81
10 pablo          パブロ               chill2023         1.72
# … with 30 more rows
# ℹ Use `print(n = ...)` to see more rows

元データとなるテーブルは、下記の2つです。この2つのテーブルから上記の1つのテーブルをイメージするのが、最初はなかなか大変かと思います。

> weapon_nawabari_drizzle2023
# A tibble: 101 × 3
   weapon           total percentage
   <chr>            <dbl>      <dbl>
 1 promodeler_rg    77082       6.22
 2 sshooter_collabo 47714       3.85
 3 sshooter         41190       3.32
 4 lact450          38169       3.08
 5 furo             36061       2.91
 6 nzap89           35047       2.83
 7 sharp_neo        31876       2.57
 8 bold             31411       2.53
 9 momiji           30076       2.43
10 wakaba           29244       2.36
# … with 91 more rows
# ℹ Use `print(n = ...)` to see more rows
> weapon_nawabari_chill2023
# A tibble: 110 × 3
   weapon           total percentage
   <chr>            <dbl>      <dbl>
 1 maneuver_collabo 39669       7.35
 2 promodeler_rg    31346       5.81
 3 sshooter_collabo 16343       3.03
 4 furo             15410       2.85
 5 sshooter         14624       2.71
 6 52gal            13780       2.55
 7 lact450          12924       2.39
 8 liter4k          12666       2.35
 9 bold             12512       2.32
10 nzap89           12237       2.27
# … with 100 more rows
# ℹ Use `print(n = ...)` to see more rows

それぞれに、 weapon と percentage の列があります。total の列は使わないので除外して、percentage の名前をリネームしてから、weapon で left_join() すると、下記のようになります。

# A tibble: 110 × 4
   weapon              buki                        drizzle2023 chill2023
   <chr>               <chr>                             <dbl>     <dbl>
 1 52gal               .52ガロン                         2.07      2.55
 2 96gal               .96ガロン                         0.185     0.193
 3 96gal_deco          .96ガロンデコ                     0.335     0.367
 4 bold                ボールドマーカー                  2.53      2.32
 5 bold_neo            ボールドマーカーネオ              0.775     0.825
 6 bottlegeyser        ボトルガイザー                    0.557     0.399
 7 bottlegeyser_foil   ボトルガイザーフォイル           NA         0.964
 8 heroshooter_replica ヒーローシューター レプリカ       1.39      1.18
 9 jetsweeper          ジェットスイーパー                0.306     0.282
10 jetsweeper_custom   ジェットスイーパーカスタム        0.974     0.867
# … with 100 more rows
# ℹ Use `print(n = ...)` to see more rows

これに gather() を使って「gather(ends_with("2023"), key = "season", value = "percentage")」とまとめたものが前述の plot_data です。

* gather 後、さらに top_n() で上位20を取り出して、fct_reorder() で並び順を指定しています。



この記事が気に入ったらサポートをしてみませんか?