Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

MITTI12101
理学療法士。メインは脳卒中。回復期リハビリテーション病棟。中間管理職。2児の父。ハーバード大学がMOOCとして提供しているデータサイエンスのコースを修了しています。 https://www.edx.org/professional-certificate/harvardx-data-science
http://www.restorative-pt.tokyo/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした