第3章ではggplot2を使ったグラフの作り方を紹介しています。
【3-1】ExcelにはないRでグラフを作るメリットと特徴
【3-2】ggplot2でグラフを作る流れを説明します
【3-3】Rのggplot2で散布図を作るgeom_point関数
【3-4】Rのggplot2でヒストグラムを作るgeom_histogram関数
【3-1】ExcelにはないRでグラフを作るメリットと特徴
【3-2】ggplot2でグラフを作る流れを説明します
【3-3】Rのggplot2で散布図を作るgeom_point関数
【3-4】Rのggplot2でヒストグラムを作るgeom_histogram関数
【3-5】Rのggplot2で密度曲線を作るgeom_density関数
【3-6】Rのggplot2で箱ひげ図を作るgeom_boxplot関数
今回は棒グラフを紹介します。
棒グラフは馴染みのあるグラフではありますが、自分の体験上「統計に慣れていない方やExcelで棒グラフと折れ線グラフ以外のグラフを作成したことがない方は気づいていない落とし穴もあるかな」とも感じています。
また、棒グラフの作り方は元のデータの集計方法によって作り方が違います。
今回は棒グラフの基本や原則、Rのggplot2を使った棒グラフの作成方法を紹介します。
エラーバーや散布図との組み合わせも紹介します。
2.棒グラフの基本的な考え方
棒の「長さ自体」に意味がある
これを書いていて当たり前のように感じるのですが、実は当たり前ではありません。
Excelで棒グラフを作るときにやってしまいがちなのですが、まず棒グラフで一番やってはいけない図を紹介します。

棒グラフはグループ毎の長さの比を見て比べるグラフですが、右図のように縦軸の最小の数字を変えてしまうと長さの比が変わってしまいます。
(171.67 - 150) / (156.42 - 150) → 21.67 / 6.42 → 3.38倍
そのため本来1.09倍しか違わないデータをあたかも3.38倍違うデータと恣意的に見せたと解釈される可能性もあります。
そのため棒グラフを使うのであれば必ず最小値は0にする必要があります。
もしくは棒グラフ以外(箱ひげ図やヒストグラム)などを考えるのも手かもしれません。
棒グラフは「データ→集計→結果」
棒グラフが使われるのは主に「集計してカウント数を表示する」場合か「平均を表示する」ときに使います。

つまり棒グラフを作るためには集計されたデータが必要になります。
【3-6】Rのggplot2で箱ひげ図を作るgeom_boxplot関数
今回は棒グラフを紹介します。
棒グラフは馴染みのあるグラフではありますが、自分の体験上「統計に慣れていない方やExcelで棒グラフと折れ線グラフ以外のグラフを作成したことがない方は気づいていない落とし穴もあるかな」とも感じています。
また、棒グラフの作り方は元のデータの集計方法によって作り方が違います。
今回は棒グラフの基本や原則、Rのggplot2を使った棒グラフの作成方法を紹介します。
エラーバーや散布図との組み合わせも紹介します。
1.データの読み込み
今回もggplotパッケージが含まれているtidyverseパッケージを読み込みます。
#tidyverseパッケージをインストールしていなければインストール。していれば次へinstall.packages("tidyverse")#既にtidyverseパッケージをインストールしている方は以下でもOKlibrary(tidyverse)
#今回のデータは以下のコードでdatというデータフレームを作成します。
#下の全てを選択しコントロール(もしくはcommand)+Entern_male <- 130n_female <- 70set.seed(2019)height <- round(c(rnorm(n_female, 157, 5), rnorm(n_male, 173, 10)), 0)sex <- c(rep("female", n_female), rep("male", n_male))class <- sample(c("A", "B", "C"), size = 200, replace = TRUE)dat <- data.frame(height, sex, class)
2.棒グラフの基本的な考え方
棒の「長さ自体」に意味がある
これを書いていて当たり前のように感じるのですが、実は当たり前ではありません。
Excelで棒グラフを作るときにやってしまいがちなのですが、まず棒グラフで一番やってはいけない図を紹介します。

棒グラフはグループ毎の長さの比を見て比べるグラフですが、右図のように縦軸の最小の数字を変えてしまうと長さの比が変わってしまいます。
(171.67 - 150) / (156.42 - 150) → 21.67 / 6.42 → 3.38倍
そのため本来1.09倍しか違わないデータをあたかも3.38倍違うデータと恣意的に見せたと解釈される可能性もあります。
そのため棒グラフを使うのであれば必ず最小値は0にする必要があります。
もしくは棒グラフ以外(箱ひげ図やヒストグラム)などを考えるのも手かもしれません。
棒グラフは「データ→集計→結果」
棒グラフが使われるのは主に「集計してカウント数を表示する」場合か「平均を表示する」ときに使います。

つまり棒グラフを作るためには集計されたデータが必要になります。
集計せずにグラフを作る方法もありますが、今回は先に集計をしてグラフを作ります。
棒グラフの3つのパターンを決めるposition
棒グラフといってもいくつかのタイプがあります。
Rではposition = "○○"を指定するだけで変更することができます。
position = "stack"(積み上げ棒グラフ)
position = "fill"(積み上げ棒グラフ(割合))
position = "dodge"(横に並べる)

用途に応じて使い分けます。
3.集計したデータを作成する
まずデータの確認をします。

性別と身長とgradeという変数があります。
このデータを以下の2つの
dat_stat_grade:grade毎に集計
dat_stat_grade_sex:gradeと性別毎に集計


group_by関数で性別ごとのグループを作り、summarize関数でグループ毎の平均・標準偏差・人数を求め、それらをパイプ演算子でつないでいます。
パイプ演算子(%>%)、group_by、summarize関数については第2章で紹介しています。
4.棒グラフの基本的な作り方
ggplot2で棒グラフを作る時にはgeom_bar関数を使います。
まずgradeごとの人数をカウントします。

geom_barではstat = "identity"が必要になります。

これはデータの集計方法で「この数字のままを使ってね」という意味になります。

5.棒の幅を変える
棒の幅を変えるにはwidthで指定します。

6.色を変える
グラフの中の色を変えるにはfillを使います。
一括で色を指定する時はaes関数の外にfillを指定します。

色の透過度を変えるにはalpha = ○○で指定します

グループ毎に色を変えるにはaes関数内に色分けしたい変数を入れます。

7.fill = ○○で別の変数を指定する。
次はdat_stat_grade_sexを使ってグラフを作成します。
x軸はgrade、y軸は人数、色を性別にします。
もしpositionを指定しないと自動的に"stack"になります。

8.position = "stack"のときのいろんな指定方法
グラフに数値を追加する
グラフに数値を追加するにはgeom_text関数を追加します。

ポイントは以下の通りです。
・aes関数の中groupをfillと揃える
・aes関数の中のlabelに表示したい変数名を指定する
・positionをgeom_barと同じにする

数値の値を棒グラフの真ん中に配置する
geom_textのposition = "stack"を行うと数値の値と同じ位置に数値がきます。
もし棒グラフの真ん中に配置する時はposition = position_stack(vjust = 0.5)に変更します。
9.position = "fill"のときのいろんな指定方法
基本的な作り方
積み上げ棒グラフ(割合)を作る時はpositionに"fill"を指定します。

縦軸は割合(0〜1)になります。
縦軸のラベルを%に変える
y軸を指定するscale_y_continuous関数を使うと縦軸のラベルを%に指定することができます。

グラフに数値を追加する
グラフに数値を追加する時はposition = "stack"でも紹介したgeom_textを使います。


もし棒グラフの真ん中に配置する時はposition = position_fill(vjust = 0.5)に変更します。

今回は身長をつかってグラフを作ります。
基本的な作り方
横に並べるにはpositionに"dodge"を指定します。

グラフの軸の表示を変える
position = "fill"のときにはy軸を指定するscale_y_continuous関数を使い桁を区切るカンマを付けることができます。今回のデータでは千を超える値がないのでカンマは出てきませんが、scale_y_continuous(labels = scales::comma)の1行を付け加えます。
グラフに値を追加する
グラフに数値を追加する時はposition = "stack"でも紹介したgeom_textを使います。


"stack"や"fill"の時と違い、geom_bar関数のpositionをposition = "dodge"とするとエラーが出ます。
position = position_dodge(○○)で数値を指定します。
グループやwidthの指定で幅が変わるので数字を変えながら丁度いい数字を探してください。
今回の場合は0.9が丁度いいようです。

ただこのままでは線と数字がかぶってしまいます。
高さを微調整する時はvjust=数値で指定します。
数値がプラスだと下に、マイナスだと上に移動します。

11.グラフにエラーバーを付ける
10で作成したデータで話を続けます。今回はエラーバーの幅を標準偏差にしています。
グラフにエラーバーをつけるにはgeom_errorbarを使います。
geom_errorbarではエラーバーの最小値(ymin)と最大値が(ymax)がいるのでaes関数に入れます。
ymin = 平均 - 標準偏差
ymax = 平均 + 標準偏差
geom_barのpositionがdodgeになっているので、上のグラフのgeom_textと同様に、geom_errorbarもposition = position_dodge(○○)で調整してください。
またgeom_textがエラーバーに重ならないようyの値を10に変更しています。自由に変えてみてください。
このように自由にグラフを重ねられるのもggplot2の魅力です。
12.棒グラフと散布図を組み合わせる
統計になれてないと分布を見ずにいきなり棒グラフを作ることがあります(自分がそうでした)。
ただなれないと棒グラフでは分布はわかりにくいです。
エラーバーも実は正規分布のデータでないと意味をなしません。
実際に発表する場面では使わないかもしれませんが、グラフになれるまではぜひ棒グラフに散布図を組み合わせてみてください。
下のグラフですが、実際の分布イメージできますか?
散布図を組み合わせるのはgeom_point(position ="jitter"を追加する)かgeom_jitterです。

棒グラフの3つのパターンを決めるposition
棒グラフといってもいくつかのタイプがあります。
Rではposition = "○○"を指定するだけで変更することができます。
position = "stack"(積み上げ棒グラフ)
position = "fill"(積み上げ棒グラフ(割合))
position = "dodge"(横に並べる)

用途に応じて使い分けます。
3.集計したデータを作成する
まずデータの確認をします。
head(dat)
str(dat)

性別と身長とgradeという変数があります。
このデータを以下の2つの
dat_stat_grade:grade毎に集計
dat_stat_grade_sex:gradeと性別毎に集計
dat_stat_grade <- dat %>% group_by(grade) %>% summarize(平均 = round(mean(身長), 2), 標準偏差 = sd(身長), 人数 = n()) dat_stat_grade

dat_stat_grade_sex <- dat %>% group_by(grade, 性別) %>% summarize(平均 = round(mean(身長), 2), 標準偏差 = sd(身長), 人数 = n()) dat_stat_grade_sex

group_by関数で性別ごとのグループを作り、summarize関数でグループ毎の平均・標準偏差・人数を求め、それらをパイプ演算子でつないでいます。
パイプ演算子(%>%)、group_by、summarize関数については第2章で紹介しています。
4.棒グラフの基本的な作り方
ggplot2で棒グラフを作る時にはgeom_bar関数を使います。
まずgradeごとの人数をカウントします。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数), stat = "identity")

geom_barではstat = "identity"が必要になります。

これはデータの集計方法で「この数字のままを使ってね」という意味になります。

5.棒の幅を変える
棒の幅を変えるにはwidthで指定します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数), width = 0.5, stat = "identity")

6.色を変える
グラフの中の色を変えるにはfillを使います。
一括で色を指定する時はaes関数の外にfillを指定します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数), fill = "red", stat = "identity")

色の透過度を変えるにはalpha = ○○で指定します
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数), fill = "red", alpha = 0.5, stat = "identity")

グループ毎に色を変えるにはaes関数内に色分けしたい変数を入れます。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数, fill = grade), alpha = 0.5, stat = "identity")

7.fill = ○○で別の変数を指定する。
次はdat_stat_grade_sexを使ってグラフを作成します。
x軸はgrade、y軸は人数、色を性別にします。
もしpositionを指定しないと自動的に"stack"になります。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), stat = "identity")

8.position = "stack"のときのいろんな指定方法
グラフに数値を追加する
グラフに数値を追加するにはgeom_text関数を追加します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), position = "stack", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 人数, group = 性別 ,label = 人数), position = "stack")

ポイントは以下の通りです。
・aes関数の中groupをfillと揃える
・aes関数の中のlabelに表示したい変数名を指定する
・positionをgeom_barと同じにする

数値の値を棒グラフの真ん中に配置する
geom_textのposition = "stack"を行うと数値の値と同じ位置に数値がきます。
もし棒グラフの真ん中に配置する時はposition = position_stack(vjust = 0.5)に変更します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), position = "stack", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 人数, group = 性別, label = 人数), position = position_stack(vjust = 0.5))
9.position = "fill"のときのいろんな指定方法
基本的な作り方
積み上げ棒グラフ(割合)を作る時はpositionに"fill"を指定します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), stat = "identity", position = "fill")

縦軸は割合(0〜1)になります。
縦軸のラベルを%に変える
y軸を指定するscale_y_continuous関数を使うと縦軸のラベルを%に指定することができます。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), stat = "identity", position = "fill")+ scale_y_continuous(labels = scales::percent)

グラフに数値を追加する
グラフに数値を追加する時はposition = "stack"でも紹介したgeom_textを使います。


もし棒グラフの真ん中に配置する時はposition = position_fill(vjust = 0.5)に変更します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 人数, fill = 性別), position = "fill", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 人数, group = 性別, label = 人数), position = position_fill(vjust = 0.5))

10.position = "dodge"のときのいろんな指定方法
今回は身長をつかってグラフを作ります。
基本的な作り方
横に並べるにはpositionに"dodge"を指定します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")

グラフの軸の表示を変える
position = "fill"のときにはy軸を指定するscale_y_continuous関数を使い桁を区切るカンマを付けることができます。今回のデータでは千を超える値がないのでカンマは出てきませんが、scale_y_continuous(labels = scales::comma)の1行を付け加えます。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")+ scale_y_continuous(labels = scales::comma)
グラフに値を追加する
グラフに数値を追加する時はposition = "stack"でも紹介したgeom_textを使います。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 平均, group = 性別, label = 平均), position = position_dodge(0.9))


"stack"や"fill"の時と違い、geom_bar関数のpositionをposition = "dodge"とするとエラーが出ます。
position = position_dodge(○○)で数値を指定します。
グループやwidthの指定で幅が変わるので数字を変えながら丁度いい数字を探してください。
今回の場合は0.9が丁度いいようです。

ただこのままでは線と数字がかぶってしまいます。
高さを微調整する時はvjust=数値で指定します。
数値がプラスだと下に、マイナスだと上に移動します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 平均, group = 性別, label = 平均), position = position_dodge(0.9), vjust = -0.5)
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")+ geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 平均, group = 性別, label = 平均), position = position_dodge(0.9), vjust = 1.5, color = "white")

11.グラフにエラーバーを付ける
10で作成したデータで話を続けます。今回はエラーバーの幅を標準偏差にしています。
グラフにエラーバーをつけるにはgeom_errorbarを使います。
geom_errorbarではエラーバーの最小値(ymin)と最大値が(ymax)がいるのでaes関数に入れます。
ymin = 平均 - 標準偏差
ymax = 平均 + 標準偏差
geom_barのpositionがdodgeになっているので、上のグラフのgeom_textと同様に、geom_errorbarもposition = position_dodge(○○)で調整してください。
またgeom_textがエラーバーに重ならないようyの値を10に変更しています。自由に変えてみてください。
このように自由にグラフを重ねられるのもggplot2の魅力です。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade_sex, aes(x = grade, y = 平均, fill = 性別), position = "dodge", stat = "identity")+ geom_errorbar(data = dat_stat_grade_sex, aes(x = grade, ymin = 平均 - 標準偏差, ymax = 平均 + 標準偏差, group = 性別), position = position_dodge(0.9), width = 0.2)+
geom_text(data = dat_stat_grade_sex, aes(x = grade, y = 10, group = 性別, label = 平均), position = position_dodge(0.9), vjust = 1.5, color = "white")
12.棒グラフと散布図を組み合わせる
統計になれてないと分布を見ずにいきなり棒グラフを作ることがあります(自分がそうでした)。
ただなれないと棒グラフでは分布はわかりにくいです。
エラーバーも実は正規分布のデータでないと意味をなしません。
実際に発表する場面では使わないかもしれませんが、グラフになれるまではぜひ棒グラフに散布図を組み合わせてみてください。
下のグラフですが、実際の分布イメージできますか?
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 平均, fill = grade), alpha = 0.5, stat = "identity")+ geom_errorbar(data = dat_stat_grade, aes(x = grade, ymin = 平均 - 標準偏差, ymax = 平均 + 標準偏差), color = "red", width = 0.2)
散布図を組み合わせるのはgeom_point(position ="jitter"を追加する)かgeom_jitterです。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 平均, fill = grade), alpha = 0.5, stat = "identity")+ geom_jitter(data = dat, aes(x = grade, y = 身長))+ geom_errorbar(data = dat_stat_grade, aes(x = grade, ymin = 平均 - 標準偏差, ymax = 平均 + 標準偏差), color = "red", width = 0.2)

ここでのポイントはgeom_jitterのdataがdatになっている点です。
これは棒グラフやエラーバーの数値は集計したデータを使いますが、散布図は200名の生データが必要になるからです。
ちなみにggplot2は下に書くほど前面に追加されます。
今回はgeom_errorbarがgeom_jitterよりも下にあるので棒が散布図の点で隠れていません。
geom_errorbarを下に書くとエラーバーが散布図の影に隠れますので確認してみてください。
13.棒グラフを横にする
このグラフを横にするのはcoord_flip()を足すだけです。
14.x軸を並べ替える
軸をyの値で並べ替えるにはx軸にreorder関数を使います。
reorder(x軸の変数名, 並べ替えたい変数名)とします。
aes(x = grade, ...) → aes(x = reorder(grade, 人数), ...)

ただx軸の名前が変になりました。そのためlabs関数でx軸のタイトルを変更します。
labs関数はx,y軸の名前やタイトル・サブタイトルを指定します。

15.凡例を消す
棒グラフの場合x軸に名前がついていて凡例がいらない場面もあります。
その時はguides(fill = "none")を付け加えます。

15.まとめ
今回は長くなりましたが、棒グラフについて紹介しました。
棒グラフには色々なpositionがあるので最初は思い通りのグラフにならないかもしれませんが、見直しながら少しずつ慣れてみてください。
今回はgeom_errorbarがgeom_jitterよりも下にあるので棒が散布図の点で隠れていません。
geom_errorbarを下に書くとエラーバーが散布図の影に隠れますので確認してみてください。
13.棒グラフを横にする
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数, fill = grade), stat = "identity")
このグラフを横にするのはcoord_flip()を足すだけです。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数, fill = grade), stat = "identity")+
coord_flip()
14.x軸を並べ替える
軸をyの値で並べ替えるにはx軸にreorder関数を使います。
reorder(x軸の変数名, 並べ替えたい変数名)とします。
aes(x = grade, ...) → aes(x = reorder(grade, 人数), ...)
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = reorder(grade, 人数), y = 人数, fill = grade), stat = "identity")

ただx軸の名前が変になりました。そのためlabs関数でx軸のタイトルを変更します。
labs関数はx,y軸の名前やタイトル・サブタイトルを指定します。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = reorder(grade, 人数), y = 人数, fill = grade), stat = "identity")+ labs(x = "grade")

15.凡例を消す
棒グラフの場合x軸に名前がついていて凡例がいらない場面もあります。
その時はguides(fill = "none")を付け加えます。
ggplot()+ theme_gray(base_family = "HiraKakuPro-W3")+ geom_bar(data = dat_stat_grade, aes(x = reorder(grade, 人数), y = 人数, fill = grade), stat = "identity")+ labs(x = "grade")+ guides(fill = "none")

15.まとめ
今回は長くなりましたが、棒グラフについて紹介しました。
棒グラフには色々なpositionがあるので最初は思い通りのグラフにならないかもしれませんが、見直しながら少しずつ慣れてみてください。