第3章ではggplot2を使ったグラフの作り方を紹介しています。


【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関数

【3-7】棒グラフの基本とRのggplot2で棒グラフを作るgeom_bar関数

今回は折れ線グラフを紹介します。

折れ線グラフは時系列の変化を追うのに適しています。

今回は実際のサイトから表を読み込んでグラフを作成します。


1.データの読み込み


今回は気象庁のサイトから東京の平均気温を読み込みます。

スクリーンショット 2019-08-19 0.19.12



webサイトからデータを抜き出すにはrvestパッケージを使います。
以下コードですが、まだ説明していないものが多いのでそのままコピー→実行すると表を読み込めます。

# まだrvestパッケージをインストールしたことなければインストール
install.packages("rvest")
# rvestを呼び出す library(rvest) # urlを指定する
url <- "https://www.data.jma.go.jp/obd/stats/etrn/view/monthly_s3.php?prec_no=44&block_no=47662&year=&month=&day=&view=" #url を読み込む。
h <- read_html(url)
# 読み込んだhtmlの中で"テーブル形式" のものを読み込む tab <- h %>% html_nodes("table")
# 読み込むと5つのtableがあることがわかる。1つずつ確認すると4つ目が目的のtableだった。tableをdata.frame型に変換する。 dat <- tab[[4]] %>% html_table
head(dat)
スクリーンショット 2019-08-19 0.34.09


2.データハンドリング

このデータをグラフにしたいのですが以下の数点が気になります。

スクリーンショット 2019-08-19 16.09.58


「年の値」の列がいらない

一番右にある「年の値」はグラフを作るには必要なさそうです。
いらない列を削除するにはselect関数を使います。





wideデータになっている

【2-5】Rでデータを集計するのに便利なlongデータとgather関数でも紹介しましたが、今回のデータはwideデータになっています。Excelではwideデータでグラフを作成しますが、Rでデータ集計、グラフを作るにはlongデータに変える必要があります。

wideデータをlongデータに変える関数はgather関数です。



今回もggplotパッケージが含まれているtidyverseパッケージを読み込みます。


気温の値に数値ではない値がある

データをよく見ると )] のように数値ではないものが含まれています。

他にもよくみられるのが1,000以上のような , も計算には邪魔です。

試しにstr関数でデータの概要を見てみます。

str(dat)

スクリーンショット 2019-08-19 16.13.21



int : 整数
num : 数値(整数以外も含む)
chr : 文字列

2月と6〜11月は文字列になっているので計算してくれません。
そのため不要な記号を消す必要があります。
まだ紹介していませんが、数値以外の全てを消すparse_number関数というものがあります。


行が多すぎる

str関数に書いてますが145行あります。このままでもグラフは作れますが、今回はデータを間引きます。
行を削除するのはslice関数を使います。

今回は1880,1885,,,,,,2015,2019年を抜き出します。

スクリーンショット 2019-08-19 0.34.09

よく見ると最初の1880年は6行目のようです。

6,11,16,,,,,と抜き出すにはseq関数を使います。

seq(6, 145, 5)
スクリーンショット 2019-08-19 16.40.38

これで6から145までを5間隔で抜き出すことができます。ちなみに2019年は145行目です。

実際のコード


select関数、gather関数、parse_number関数、slice関数、この後グラフを作るggplot2関数は全てtidyverseパッケージに含まれています。

#tidyverseパッケージをインストールしていなければインストール。

install.packages("tidyverse")

#既にtidyverseパッケージをインストールしている方は以下でもOK

library(tidyverse)

もしRの基礎を勉強中であれば上のヒントでデータハンドリングを試してみてください。
いくつか方法はありますが、以下1例です。

dat_long <- dat %>% select(-年の値) %>% slice(seq(6, 145, 5), 145) %>% gather(key = 月, value = 気温, -年, factor_key = FALSE) %>% mutate(気温 = parse_number(気温)) %>%
ポイントは以下のとおりです。
・gather関数でlongデータにする前にselect関数,slice関数を使いました。
・gather関数でfactor_key = TRUEをすれば1月,2月,,,となり、入れないと10月,11月,12月,1月,,,となります。
・parse_number関数はgather関数の後で使いました(1列で済むため)。
・parse_number関数はmutate関数とセットで使う

スクリーンショット 2019-08-19 22.10.57

スクリーンショット 2019-08-19 22.15.21

1880年の1月,2月,,,と並んでいませんがグラフ作成に支障はありません。

これでデータの完成です。

3.折れ線グラフの基本的な作り方

折れ線グラフを作る時はgeom_line関数を使います。
aes関数の中でgroupを設定します。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年))

スクリーンショット 2019-08-20 11.48.02


もしgroupを指定しないと目的のグラフになりません。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温))
スクリーンショット 2019-08-20 11.48.11




4.group毎に色を変える

group毎に色を変えるにはcolor(もしくはcol)を指定します。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, color = 年))
スクリーンショット 2019-08-20 11.47.49

色の薄い最近の方が暑いのがわかります。

今回色がグラデーションになっています。これは年の型がint型(数値)になっているためです。
数値でなくfactorに変換するとグラデーションではなくなります。as.factor関数(もしくはfactor関数)を使います。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, color = as.factor(年)))
スクリーンショット 2019-08-20 11.49.29

数が多すぎてどの色が何年かわからなくなりました・・・
ただgroupの数が少ない時は便利です。


5.グラデーションの色を指定する
グラデーションの色を指定するにはscale_colour_gradientn関数を使います。
scale_color_gradientn(c("最小値の色", "最大値の色"))と指定します。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, color = 年)) + scale_colour_gradientn(colours = c("black", "red"))
スクリーンショット 2019-08-20 11.47.37



最初と最後だけでなく、途中の色も指定できます。
ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, color = 年)) + scale_colour_gradientn(colours = c("blue", "yellow", "red"))
スクリーンショット 2019-08-20 11.47.21


6.線の色を透過させる

線が重なっているところは新しい線が上書きしています。
第3章では何度も紹介していますが、色の透過はalphaで指定します。groupに関わらず一括で指定するのでaes関数の外で指定します。

ggplot() + theme_gray(base_family = "HiraKakuPro-W3") + geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, color = 年), alpha = 0.5) + scale_colour_gradientn(colours = c("blue", "yellow", "red"))
スクリーンショット 2019-08-20 11.47.09


ちなみに年を間引かなければこのようになります。

スクリーンショット 2019-08-20 11.43.46


こうみても気温が少しずつ上昇している傾向が伺えます。


7.折れ線グラフに点をつける

もう少しデータを間引き、1880年と2018年のデータだけにします。
dat_long <- 
  dat %>% 
    select(-年の値) %>% 
    slice(6, 144) %>% 
    gather(key = 月, value = 気温, -年, factor_key = TRUE) %>% 
    mutate(気温 = parse_number(気温))


折れ線につける点は折れ線グラフに散布図を重ねます。
散布図は【3-3】Rのggplot2で散布図を作るgeom_point関数で紹介しました。
ggplot() + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(data = dat_long, aes(x = 月, y = 気温, group = 年, col = as.factor(年)), alpha = 0.5) +
  geom_point(data = dat_long, aes(x = 月, y = 気温, col = as.factor(年)))
スクリーンショット 2019-08-20 15.29.42



上のコードではdata=とaes()の一部が同じです。このように同じデータ、aesを使う場合はggplot()に入れる事ができます。加えてラベルのas.factor(年)の見栄えをlabs関数で変更します。
ggplot(data = dat_long, aes(x = 月, y = 気温, col = as.factor(年))) + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(aes(group = 年), alpha = 0.5) +
  geom_point() +
  labs(color = "")
スクリーンショット 2019-08-20 19.24.13


8.線のタイプを変更する


線のタイプはlinetypeで指定します。
注意点としてはgeom_point関数のshape時に紹介しましたがfactor型にする必要があります。



ggplot(data = dat_long, aes(x = 月, y = 気温)) + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(aes(group = as.factor(年), linetype= as.factor(年)), alpha = 0.5) +
  geom_point()
スクリーンショット 2019-08-20 19.26.21

9.数値を入れる場合

数値を追加するにはgeom_text関数が使えますが、数値の位置が点の位置と重なってしまいます。
加えて右のラベルの点とaが重なって見栄えが悪いです。

ggplot(data = dat_long, aes(x = 月, y = 気温, col = as.factor(年))) + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(aes(group = 年), alpha = 0.5) +
  geom_text(aes(label = 気温)) +
  geom_point()
スクリーンショット 2019-08-20 19.29.02



vjustで上下にずらすことができます。ただそもそも点の位置が近いとどうしても重なります。
ラベルに表示させないためにはshow.legend=FALSEを指定します。

ggplot(data = dat_long, aes(x = 月, y = 気温, col = as.factor(年))) + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(aes(group = 年), alpha = 0.5) +
  geom_text(aes(label = 気温), vjust = 1.5, show.legend = FALSE) +
  geom_point()
スクリーンショット 2019-08-20 19.28.12




文字が重なって困る時は自動的に場所を調整してくれるgeom_text-repel関数が使えます。

ただgeom_text_repel関数はtidyverseパッケージに入ってません。ggrepelパッケージのインストールが必要です。

#一度も使ったことがなければインストール
install.packages("ggrepel") #インストール後はlibraryで呼び出す
library(ggrepel)
geom_text → geom_text_repelに変更するだけで自動調整してくれます。
ggplot(data = dat_long, aes(x = 月, y = 気温, col = as.factor(年))) + 
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_line(aes(group = 年), alpha = 0.5) +
  geom_text_repel(aes(label = 気温), show.legend = FALSE) +
  geom_point()
スクリーンショット 2019-08-20 19.26.34




10.まとめ

今回は折れ線グラフの作成について紹介しました。

折れ線グラフではgroupの指定が重要だと感じています。

またRを使ったグラフ作成はデータハンドリングが大半を締めますので、なれない方は第2章を参考にしてください。


第3章ではggplot2を使ったグラフの作り方を紹介しています。


【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を使った棒グラフの作成方法を紹介します。
エラーバーや散布図との組み合わせも紹介します。


1.データの読み込み

今回もggplotパッケージが含まれているtidyverseパッケージを読み込みます。
#tidyverseパッケージをインストールしていなければインストール。していれば次へ

install.packages("tidyverse")

#既にtidyverseパッケージをインストールしている方は以下でもOK

library(tidyverse)

#今回のデータは以下のコードでdatというデータフレームを作成します。
#下の全てを選択しコントロール(もしくはcommand)+Enter

n_male <- 130
n_female <- 70
set.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で棒グラフを作るときにやってしまいがちなのですが、まず棒グラフで一番やってはいけない図を紹介します。

スクリーンショット 2019-08-06 11.58.31



棒グラフはグループ毎の長さの比を見て比べるグラフですが、右図のように縦軸の最小の数字を変えてしまうと長さの比が変わってしまいます。

(171.67 - 150) / (156.42 - 150) → 21.67 / 6.42 → 3.38倍

そのため本来1.09倍しか違わないデータをあたかも3.38倍違うデータと恣意的に見せたと解釈される可能性もあります。

そのため棒グラフを使うのであれば必ず最小値は0にする必要があります。
もしくは棒グラフ以外(箱ひげ図やヒストグラム)などを考えるのも手かもしれません。




棒グラフは「データ→集計→結果」

棒グラフが使われるのは主に「集計してカウント数を表示する」場合か「平均を表示する」ときに使います。


スクリーンショット 2019-08-06 11.59.44


つまり棒グラフを作るためには集計されたデータが必要になります。
集計せずにグラフを作る方法もありますが、今回は先に集計をしてグラフを作ります。




棒グラフの3つのパターンを決めるposition

棒グラフといってもいくつかのタイプがあります。
Rではposition = "○○"を指定するだけで変更することができます。

position = "stack"(積み上げ棒グラフ)

position = "fill"(積み上げ棒グラフ(割合))

position = "dodge"(横に並べる)

スクリーンショット 2019-08-06 12.08.53

用途に応じて使い分けます。



3.集計したデータを作成する

まずデータの確認をします。

head(dat)
str(dat)
スクリーンショット 2019-08-06 14.10.32


性別と身長と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
スクリーンショット 2019-08-06 16.57.54


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

dat_stat_grade_sex
スクリーンショット 2019-08-06 17.00.22



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")


スクリーンショット 2019-08-06 17.07.17

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

スクリーンショット 2019-08-06 17.05.52

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

スクリーンショット 2019-08-06 17.13.02

5.棒の幅を変える

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

ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_bar(data = dat_stat_grade, aes(x = grade, y = 人数), width = 0.5, stat = "identity")
スクリーンショット 2019-08-06 19.43.43



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")
スクリーンショット 2019-08-06 18.11.38


色の透過度を変えるには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")
スクリーンショット 2019-08-06 18.15.02


グループ毎に色を変えるには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")
スクリーンショット 2019-08-06 18.27.11



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")
スクリーンショット 2019-08-06 19.15.28




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")
スクリーンショット 2019-08-06 20.33.04


ポイントは以下の通りです。

・aes関数の中groupをfillと揃える
・aes関数の中のlabelに表示したい変数名を指定する
・positionをgeom_barと同じにする

スクリーンショット 2019-08-06 20.29.44


数値の値を棒グラフの真ん中に配置する

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))
スクリーンショット 2019-08-06 20.53.53





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")
スクリーンショット 2019-08-06 19.15.40


縦軸は割合(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)
スクリーンショット 2019-08-06 19.27.45



グラフに数値を追加する

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

スクリーンショット 2019-08-06 21.03.42

スクリーンショット 2019-08-06 21.05.15

もし棒グラフの真ん中に配置する時は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))

スクリーンショット 2019-08-06 21.06.18



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")
スクリーンショット 2019-08-08 20.01.48



グラフの軸の表示を変える

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))
スクリーンショット 2019-08-06 23.36.46

スクリーンショット 2019-08-06 23.40.19


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

スクリーンショット 2019-08-06 23.35.30



ただこのままでは線と数字がかぶってしまいます。
高さを微調整する時は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)
スクリーンショット 2019-08-06 23.45.44

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")
スクリーンショット 2019-08-06 23.45.53


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")
スクリーンショット 2019-08-07 0.24.19


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)
スクリーンショット 2019-08-07 0.52.41


散布図を組み合わせるのは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)
スクリーンショット 2019-08-07 0.52.29


ここでのポイントはgeom_jitterのdataがdatになっている点です。
これは棒グラフやエラーバーの数値は集計したデータを使いますが、散布図は200名の生データが必要になるからです。

ちなみにggplot2は下に書くほど前面に追加されます。
今回は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")
スクリーンショット 2019-08-07 1.02.21
ただ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")
スクリーンショット 2019-08-07 1.05.34

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")
スクリーンショット 2019-08-07 1.06.37


15.まとめ

今回は長くなりましたが、棒グラフについて紹介しました。

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






第3章ではggplot2を使ったグラフの作り方を紹介しています。


【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関数

今回は箱ひげ図(boxplot)を紹介します。

箱ひげ図は正規分布でないデータやマンホイットニーのU検定などノンパラメトリックの検定で使われます。RコマンダーやEZRでも検定と一緒に箱ひげ図が出てきますが、変数名が日本語だと□□と文字化けしてしまいます。Rstudioでggplot関数を使えば文字化け対策やグループ毎に色を付けるなどきれいなグラフが作れます。

1.データの読み込み

今回もggplotパッケージが含まれているtidyverseパッケージを読み込みます。
#tidyverseパッケージをインストールしていなければインストール。していれば次へ

install.packages("tidyverse")

#既にtidyverseパッケージをインストールしている方は以下でもOK

library(tidyverse)

#データ取り込みます。今回はdatという変数にデータを入れます

url <- "https://github.com/mitti1210/myblog/blob/master/heights.csv?raw=true"
dat <- read.csv(url)

このデータはヒストグラムを作る時に作ったデータと同じものを使用しています。



2.箱ひげ図(boxplot)とは?


箱ひげ図は以下のようなグラフです。

スクリーンショット 2019-07-21 23.28.32


棒グラフは「平均値」だけですが、箱ひげ図は「最小値, 第一四分位数, 中央値, 第三四分位数, 最大値」を示します。
また「ひげ」の外にあるデータは「外れ値」として点で表示され、大まかな分布を知ることができます。



3.四分位とは

四分位範囲も含め箱ひげ図で表示されるデータは全て「順位」で決められています。スクリーンショット 2019-07-22 1.00.16

これらはqantile関数で直接求めることができます。



4.箱ひげ図の特徴

(平均ではなく)中央値を比較するのに向いている

箱ひげ図は平均ではなく中央値を表示します。
そのため正規分布でないデータやノンパラメトリックの検定でよく使われます。

スクリーンショット 2019-07-22 1.18.14


簡易的な分布がわかる

棒グラフ±標準偏差ではある程度の分布は示してくれますが、実際今回のデータの最大値・最小値がどうだったのか等は教えてくれません。それに比べ箱ひげ図はある程度の分布を表してくれます。

ただ注意したいのが、データに二峰性の分布があると箱ひげ図でも分布がうまく反映できません。


スクリーンショット 2019-07-22 1.10.06



グラフを使って何を示したいのか?が大切になってきます。


5.箱ひげ図の基本的な作り方

ggplot2でヒストグラムを作る時にはgeom_boxplot関数を使います。
ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長), data = dat)
スクリーンショット 2019-07-17 1.12.03

6.線の色を変える

線の色を変える時はcolor = ○○を使います。

ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長), color = "red", data = dat)


スクリーンショット 2019-07-17 1.12.10


7.中に色をぬる

中の色はfill = ○○を使います。
ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長), fill = "red", data = dat)

スクリーンショット 2019-07-17 1.12.19


色を薄くする時はalpha = ○○を使います。
alphaは0〜1の値を選択します。

ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長), fill = "red", alpha = 0.5, data = dat)


スクリーンショット 2019-07-17 1.12.26


8.グループ毎に色を変える

グループ毎に色を指定するにはaes関数の中にcolorやfillを入れます。
ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長, fill = 性別), alpha = 0.5, data = dat)


スクリーンショット 2019-07-17 1.12.32

9.応用編:グラフを横にする

グラフの向きを横にするにはcoord_flip()を使います。()の中は何も入れません。

ggplot()+
  theme_gray(base_family = "HiraKakuPro-W3")+
  geom_boxplot(aes(x = 性別, y = 身長, fill = 性別), alpha = 0.5, data = dat)+
  coord_flip()



スクリーンショット 2019-07-17 1.12.38




10.応用編:ひげ(wisker)の求め方


箱ひげ図は「最小値, 第一四分位数, 中央値, 第三四分位数, 最大値」を示します。
ただ上記のグラフのようにひげは外れ値がなければひげの上端・下端が最大・最小値になるのですが、男性のように外れ値があると髭の長さは上記のどれにも当てはまりません。

もしひげの上端(下端)の値が実際何なんなのか?をこちらの記事で紹介しています。



ひげの上端・下端を求める関数を自作しました。もう少し勉強してみたい方はこちらもご参照ください。


11.まとめ

今回は箱ひげ図を紹介しました。

RコマンダーやEZRで納得の行く箱ひげ図にならなかった場合に是非試してみてください。

↑このページのトップヘ