LoginSignup
10
9

More than 3 years have passed since last update.

ggplot2で100%積み重ね棒グラフの真ん中に値を表示させたい

Last updated at Posted at 2019-05-28

はじめに

Rのggplot2で棒グラフを作成する際数字を入れたい場面があります。

スクリーンショット 2019-05-28 9.48.08.png

やり方をいつも忘れてしまうので、いつもkaztanさんの記事やR Graphics Cookbook, 2nd editionを参考にさせて頂いています。ただこの方法はposition = "stack"の積み上げ棒グラフで、縦軸はカウントデータになっています。

position = "fill"の100%積み上げ棒グラフでも数値を真ん中に配置する方法を調べようとしたのですが、google検索の上位表示に出てきませんでした。

今回は備忘録のために自分が行った方法を紹介します。

ライブラリの読み込み

#tidyverseパッケージを使ったことがなければインストールします
if(!require(tidyverse)) install.packages("tidyverse", repos = "http://cran.us.r-project.org")

#既にtidyverseパッケージをインストールしている方はライブラリで読み込みます
library(tidyverse)

今回はggplot2を使うためにtidyverseパッケージを使います。

データの作成

#データ作成
set.seed(2019)
sex <- sample(c("male", "female"), size = 200, replace = TRUE)
category <- sample(c("A","B","C","D"), size = 200, prob = c(0.2, 0.3, 0.4, 0.1), replace = TRUE)
dat <- data.frame(sex, category)
rm(sex, category)
summary(dat)
#結果
     sex      category
 female: 91   A:33    
 male  :109   B:63    
              C:90    
              D:14  
#積み上げ棒グラフ(position = "fill")
dat %>% 
  group_by(sex, category) %>% 
  summarize(count = n()) %>% 
  arrange(sex, desc(category)) %>% 
  mutate(label_y = (cumsum(count) - 0.5 * count) / sum(count)) %>%
  ggplot2::ggplot(aes(x = sex))+
  geom_bar(aes(y = count, fill = category), stat = "identity", position = "fill")+
  geom_text(aes(label = count, y = label_y))+
  scale_y_continuous(labels = scales::percent)

スクリーンショット 2019-05-28 8.25.42.png

group_bysummarize関数で集計した後グラフを作成しています。
棒グラフを作るのはgeom_bar、数値はgeom_textを用いています。

ポイント1

geom_bar関数で作る棒グラフはカテゴリーの順番毎に上から並びます。
cumsum関数で累積和を求めるのですが、そのまま行うと累積和の順番が逆になります。
そのためarrange(sex, desc(category))で逆順にしています。

#arrangeを使わなかった場合
dat %>% 
  group_by(sex, category) %>% 
  summarize(count = n()) %>% 
  mutate(label_y = (cumsum(count) - 0.5 * count) / sum(count)) 
>
  sex    category count label_y
  <fct>  <fct>    <int>   <dbl>
1 female A           16  0.0879
2 female B           31  0.346 
3 female C           36  0.714 
4 female D            8  0.956 
5 male   A           17  0.0780
6 male   B           32  0.303 
7 male   C           54  0.697 
8 male   D            6  0.972 
#arrangeを使った場合
dat %>% 
  group_by(sex, category) %>% 
  summarize(count = n()) %>% 
  arrange(sex, desc(category)) %>% 
  mutate(label_y = (cumsum(count) - 0.5 * count) / sum(count)) 
>
  sex    category count label_y
  <fct>  <fct>    <int>   <dbl>
1 female D            8  0.0440
2 female C           36  0.286 
3 female B           31  0.654 
4 female A           16  0.912 
5 male   D            6  0.0275
6 male   C           54  0.303 
7 male   B           32  0.697 
8 male   A           17  0.922 

ポイント2

通常の積み上げ棒グラフであればmutate(label_y = cumsum(count) - 0.5 * count)で高さを求めます。

100%積み上げ棒グラフの場合は、上で求めた値をsum(count)で割ることで割合になります。

まとめ

色々書いたのですが、結果通常の積み上げ棒グラフで行う方法に対しsum()で割ればよいという話でした。

参考

ggplot2で積み重ね棒グラフに値を表示させたい

R Graphics Cookbook, 2nd edition

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9