第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章を参考にしてください。