棒グラフ
Text Update: 11/10, 2018 (JST)

棒グラフは複数の値を比較するために使われることが多いグラフです。棒の高さ、または、長さで値の大小を比較します。また、横軸に時系列データを取ることで時系列の推移を見るためにも使われる場合があります。なお、ヒストグラムと異なり棒グラフの面積に意味はありません。
 

Packages and Datasets

本ページではR version 3.4.4 (2018-03-15)の標準パッケージ以外に以下の追加パッケージを用いています。
 

Package Version Description
tidyverse 1.2.1 Easily Install and Load the ‘Tidyverse’

 
また、本ページでは以下のデータセットを用いています。
 

Dataset Package Version Description
mpg ggplot2 3.1.0 Fuel economy data from 1999 and 2008 for 38 popular models of car

 

標準パッケージを用いる方法

標準パッケージを用いて箱ひげ図を描くにはbarplot関数を用います。barplot関数は引数に高さ(height)、すなわち、Y軸の値を取りますのであらかじめY軸の値を計算しておく必要があります。
 

ggplot2::mpg %>% 
  dplyr::group_by(class) %>% 
  dplyr::summarise(cty = mean(cty, na.rm = TRUE)) %>% 
  with(., barplot(cty, names.arg = class, ylab = "Ctyモードでの平均燃費"))

残念ながらあまり使い勝手のいい関数とは言えません。
 

追加パッケージを用いる方法

ggplot2パッケージにはggplot2::geom_barという棒グラフを描くための関数が用意されています。ggplot2::geom_bar関数はデフォルトで横軸に因子水準を縦軸に度数を取ります。縦軸に統計量などを取りたい場合にはオプション指定が必要です。
 

基本的な棒グラフ

前述のようにggplot2::geom_bar関数は縦軸に度数を取ります。例えばggplot2::mpgデータセットのclassデータを指定すると以下のように度数がグラフ化されていることが分かります。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class)) +
    ggplot2::geom_bar()

ggplot2::mpg %>% 
  dplyr::count(class) %>% 
  tidyr::spread(key = class, value = n)
## # A tibble: 1 x 7
##   `2seater` compact midsize minivan pickup subcompact   suv
##       <int>   <int>   <int>   <int>  <int>      <int> <int>
## 1         5      47      41      11     33         35    62

 

統計量で描く

(要約)統計量を棒グラフで比較する場合にはggplot2::geom_bar関数のstatオプションに"identitiy"を指定します。
 

ggplot2::mpg %>% 
  dplyr::group_by(class) %>% 
  dplyr::summarise(mean = mean(cty)) %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, y = mean)) + 
    ggplot2::geom_bar(stat = "identity") +
    ggplot2::labs(y = "Cityモードでの平均燃費")

ggplot2::mpg %>% 
  dplyr::group_by(class) %>% 
  dplyr::summarise(mean = mean(cty, na.rm = TRUE)) %>% 
  dplyr::mutate(mean = round(mean, 1)) %>% 
  tidyr::spread(key = class, value = mean)
## # A tibble: 1 x 7
##   `2seater` compact midsize minivan pickup subcompact   suv
##       <dbl>   <dbl>   <dbl>   <dbl>  <dbl>      <dbl> <dbl>
## 1      15.4    20.1    18.8    15.8     13       20.4  13.5

 

層別に描く

ggplot2::geom_bar関数を用いて層別棒グラフを描く場合には縦軸に何を指定しているかをで描き方が異なりますので注意してください。

度数の場合

縦軸が度数の場合は他のggplot2::geom_系関数と同様にfillオプションを指定することで積上げ棒グラフを描くことができます。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, fill = trans)) +
    ggplot2::geom_bar(alpha = 0.75)

ggplot2::mpg %>% 
  dplyr::count(class, trans) %>% 
  tidyr::spread(key = class, value = n)
## # A tibble: 10 x 8
##    trans      `2seater` compact midsize minivan pickup subcompact   suv
##    <chr>          <int>   <int>   <int>   <int>  <int>      <int> <int>
##  1 auto(av)          NA       2       3      NA     NA         NA    NA
##  2 auto(l3)          NA       1      NA       1     NA         NA    NA
##  3 auto(l4)           1       8      14       8     12         11    29
##  4 auto(l5)          NA       4       5      NA      8          4    18
##  5 auto(l6)          NA      NA      NA       2     NA         NA     4
##  6 auto(s4)          NA       2       1      NA     NA         NA    NA
##  7 auto(s5)          NA       2      NA      NA     NA         NA     1
##  8 auto(s6)           1       5       6      NA     NA          1     3
##  9 manual(m5)        NA      18       9      NA      8         16     7
## 10 manual(m6)         3       5       3      NA      5          3    NA

 
これを比率で描きたい場合はggplot2::geom_bar関数でposition = "fill"を指定してください。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, fill = trans)) +
    ggplot2::geom_bar(position = "fill", alpha = 0.75)

 

統計量の場合

縦軸が統計量の場合は積上げ棒グラフを描く意味はありませんので集合棒グラフとして描きます。集合棒グラフを描くにはposition = "dodge"オプションを指定してください。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, y = cty, fill = trans)) + 
    ggplot2::stat_summary(geom = "bar", fun.y = "mean", position = "dodge",
                          na.rm = TRUE, alpha = 0.75) + 
    ggplot2::labs(y = "Cityモードでの平均燃費")

ggplot2::mpg %>% 
  dplyr::group_by(class, trans) %>% 
  dplyr::summarise(mean = mean(cty, na.rm = TRUE)) %>% 
  dplyr::mutate(mean = round(mean, 1)) %>% 
  tidyr::spread(key = class, value = mean)
## # A tibble: 10 x 8
##    trans      `2seater` compact midsize minivan pickup subcompact   suv
##    <chr>          <dbl>   <dbl>   <dbl>   <dbl>  <dbl>      <dbl> <dbl>
##  1 auto(av)        NA      19.5    20.3    NA     NA         NA    NA  
##  2 auto(l3)        NA      24      NA      18     NA         NA    NA  
##  3 auto(l4)        15      20.2    18.6    15.5   12.9       20.5  13.2
##  4 auto(l5)        NA      16.2    17.8    NA     12.6       20    13.3
##  5 auto(l6)        NA      NA      NA      16     NA         NA    12.5
##  6 auto(s4)        NA      20      16      NA     NA         NA    NA  
##  7 auto(s5)        NA      20      NA      NA     NA         NA    12  
##  8 auto(s6)        15      20.2    17.5    NA     NA         20    12.3
##  9 manual(m5)      NA      21      19.4    NA     13.8       21.1  16.7
## 10 manual(m6)      15.7    19.4    21      NA     12.6       17    NA

 
集合棒グラフが見難い場合にはggplot2::facet_関数群を利用してください。
 

ggplot2::mpg %>% 
  dplyr::group_by(class, trans) %>% 
  dplyr::summarise(mean = mean(cty)) %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, y = mean, fill = class)) + 
    ggplot2::geom_bar(stat = "identity") +
    ggplot2::labs(y = "Cityモードでの平均燃費") + 
    ggplot2::facet_wrap(~ trans)

 

円グラフ

ggplot2パッケージにおける円グラフは棒グラフの軸をggplot2::coord_polar関数で円周方向に変換したものです。なので、描画自体にはggplot2::geom_bar関数を用います。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = NA, fill = class)) +
    ggplot2::geom_bar(width = 1, alpha = 0.75) +
    ggplot2::coord_polar(theta = "y")

ggplot2::mpg %>% 
  dplyr::count(class) %>% 
  tidyr::spread(key = class, value = n)
## # A tibble: 1 x 7
##   `2seater` compact midsize minivan pickup subcompact   suv
##       <int>   <int>   <int>   <int>  <int>      <int> <int>
## 1         5      47      41      11     33         35    62

 
なので、層別円グラフを描く場合でも層別棒グラフを軸変換するだけです。
 

ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, fill = trans)) +
    ggplot2::geom_bar(width = 1, alpha = 0.75) +
    ggplot2::coord_polar(theta = "y")

ggplot2::mpg %>% 
  dplyr::count(class, trans) %>% 
  tidyr::spread(key = class, value = n)
## # A tibble: 10 x 8
##    trans      `2seater` compact midsize minivan pickup subcompact   suv
##    <chr>          <int>   <int>   <int>   <int>  <int>      <int> <int>
##  1 auto(av)          NA       2       3      NA     NA         NA    NA
##  2 auto(l3)          NA       1      NA       1     NA         NA    NA
##  3 auto(l4)           1       8      14       8     12         11    29
##  4 auto(l5)          NA       4       5      NA      8          4    18
##  5 auto(l6)          NA      NA      NA       2     NA         NA     4
##  6 auto(s4)          NA       2       1      NA     NA         NA    NA
##  7 auto(s5)          NA       2      NA      NA     NA         NA     1
##  8 auto(s6)           1       5       6      NA     NA          1     3
##  9 manual(m5)        NA      18       9      NA      8         16     7
## 10 manual(m6)         3       5       3      NA      5          3    NA
ggplot2::mpg %>% 
  ggplot2::ggplot(ggplot2::aes(x = class, fill = trans)) +
    ggplot2::geom_bar(position = "fill", width = 1, alpha = 0.75) +
    ggplot2::coord_polar(theta = "y")

ggplot2::mpg %>% 
  dplyr::count(class, trans) %>% 
  tidyr::spread(key = class, value = n) %>% 
  tidyr::gather(key, value, -trans) %>% 
  dplyr::mutate(value = dplyr::if_else(is.na(value), 0L, value)) %>% 
  tidyr::spread(key, value) %>% 
  dplyr::mutate_if(is.numeric, prop.table) %>% 
  tidyr::gather(key, value, -trans) %>% 
  dplyr::mutate(value = dplyr::if_else(value == 0, NA_real_, round(value, 2))) %>% 
  tidyr::spread(key, value)
## # A tibble: 10 x 8
##    trans      `2seater` compact midsize minivan pickup subcompact    suv
##    <chr>          <dbl>   <dbl>   <dbl>   <dbl>  <dbl>      <dbl>  <dbl>
##  1 auto(av)        NA      0.04    0.07   NA     NA         NA    NA    
##  2 auto(l3)        NA      0.02   NA       0.09  NA         NA    NA    
##  3 auto(l4)         0.2    0.17    0.34    0.73   0.36       0.31  0.47 
##  4 auto(l5)        NA      0.09    0.12   NA      0.24       0.11  0.290
##  5 auto(l6)        NA     NA      NA       0.18  NA         NA     0.06 
##  6 auto(s4)        NA      0.04    0.02   NA     NA         NA    NA    
##  7 auto(s5)        NA      0.04   NA      NA     NA         NA     0.02 
##  8 auto(s6)         0.2    0.11    0.15   NA     NA          0.03  0.05 
##  9 manual(m5)      NA      0.38    0.22   NA      0.24       0.46  0.11 
## 10 manual(m6)       0.6    0.11    0.07   NA      0.15       0.09 NA

 


CC BY-NC-SA 4.0 , Sampo Suzuki