タグ:グラフ

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

【3-8】ggplot2で折れ線グラフを作るgeom_line関数

【3-9】ggplot2でヒートマップを作るgeom_tile関数

【3-10】Rのggplot2でグループ毎にグラフを作りまとめて表示するfacet_wrap関数

【3-11】Rのggplot2で作った複数のグラフを1つにまとめるgridExtraパッケージ


今まで基本的なグラフの作り方について紹介しましたが、ggplot2は他にも様々なな調整やができます。


今回はグラフを作るときに参考になるサイトを紹介します。


質・量共にこのサイトより充実しているものばかりですが、ある程度慣なれていないと読み解けない箇所もあります。(初心者に向けた)説明の細かさはこのサイトが1番だと思いますので、困ったらこのサイトで確認してください。



チートシート
チートシートとは直訳するとカンニングペーパーという意味で、スライド1〜2枚でその機能を確認できる便利シートになります。基本的な使い方でこまればまずはチートシートを確認しています。

Rにもいろいろなチートシートがあり、ggplot2のチートシートもあります。
ggplot2のチートシートはRStudioのヘルプ→Cheetsheetsにあります(英語版)。

スクリーンショット 2019-10-08 21.44.51

また日本語版もありますのでダウンロードしてお使いください。



書籍

RユーザのためのRStudio[実践]入門
−tidyverseによるモダンな分析フローの世界

松村 優哉 (著), 湯谷 啓明 (著), 紀ノ定 保礼 (著), 前田 和寛 (著)

通称「宇宙本」
この本は初めてRを勉強する方に最初に進めている本です。
Rの基本的な操作から第2章で行ったデータハンドリング、第3章で行ったggplot2によるグラフ作成も紹介されています。他にもウェブスクレイピングやレポートの作成などRを使ってデータ分析を行いたい方にはピッタリはまると思います。


Rグラフィックスクックブック ―ggplot2によるグラフ作成のレシピ集

この本ではggplot2の細かい使い方が紹介されている辞書的な1冊です。
ただ2013年の本なのでRやggplotのバージョンの問題で上手く動かないものがあるというコメントもあります。
実はこの本の第2版がオンラインで無料で読むことができます(英語)。



サイト

グラフ描画ggplot2の辞書的まとめ20のコード

ggplot2による可視化入門


biostatistics

これらのサイトはggplot2の基本的な使い方や代表的なグラフ、オプションの説明があります。
まだ慣れない時期はこれらのサイトを見比べながら少しずつイメージを掴むようにしてました。


From Data to Viz
スクリーンショット 2019-10-08 22.59.39



海外のサイトですが用途を選べばどのグラフを使えばいいか、そのコードサンプルを表示してくれます。そもそもどんなグラフを使えばいいか分からない場合は参考になります。




R Graphics Cookbook, 2nd edition
先程の「Rグラフィックスクックブック」の第2版です。
英語版では書籍がありますが、オンライ版は無料となっています。
ggplot2の辞書的な使い方ができますので、困ったことがあるとよくお世話になっています。
英語ではありますが、第3章を一通り試す+google翻訳でも参考になる部分は大きいと思っています。

Data Visualization
こちらも英語版ではありますが、Rを使ったグラフ作成について考え方から実際のコードまで紹介されています。中上級変ではありますが勉強になります。

Introduction to Data Science
私がRを勉強するのに利用したMOOC(Edx)のテキストです。英語ですが無料で読めます。
ggplot2に関しても詳しい説明があります。
こちらではデータ視覚化の原則(これだけは絶対にするな集)もあるので一読を進めます!



r-wakalang
Rに関するどんな質問でも気軽に相談できるslackになります。
Rは実はコミュニティーが平和で、初心者的な質問でも誰かがわかりやすく回答してくれる非常に珍しい(貴重な!)場になっています。
ggplot2に関してのスレッドもあります。


まとめ
今回はRのggplot2を使うときに参考になる書籍やサイトを紹介しました。
これからも参考になる情報があれば更新したいと思います。

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

【3-8】ggplot2で折れ線グラフを作るgeom_line関数

【3-9】ggplot2でヒートマップを作るgeom_tile関数



【3-10】Rのggplot2でグループ毎にグラフを作りまとめて表示するfacet_wrap関数では3つのグラフを作成しました。今回はその3つのグラフを並べて1つのグラフにしてしまうgridExtraパッケージを紹介します。


1.使用するデータ

今回は【3-10】Rのggplot2でグループ毎にグラフを作りまとめて表示するfacet_wrap関数で取り込んだデータを使用します。データやコードについては以下をご参照ください。


今回はtidyverseパッケージに加えgridExtraパッケージを使用します。

上記パッケージを一度も使ったことがなければインストールします。
install.packages("tidyverse")
既にインストールしていればlibrary関数で呼び出します。
library(tidyverse) 


macの日本語文字化け対策にヒラギノ角ゴ Pro W3 ("HiraKakuPro-W3"を使っています。
windowの場合はエラーが出るかもしれませんのでtheme_gray(base_family = "HiraKakuPro-W3") +をの色をつけた箇所を消してください。

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

dat_stat <-
  dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
    group_by(項目, sheet) %>% 
    summarize(平均 = mean(点数)) %>% 
    mutate(平均 = round(平均, 1)) 

p_1 <-
dat_stat %>% 
  filter(項目 == "合計") %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")

p_2 <-
dat_stat %>% 
  filter(項目 %in% c("運動合計", "認知合計")) %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")

p_3 <-
dat_stat %>% 
  filter(!項目 %in% c("運動合計", "認知合計", "合計")) %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")
スクリーンショット 2019-08-24 1.07.31
スクリーンショット 2019-08-24 1.07.41
スクリーンショット 2019-08-24 1.07.55


2.gridExtraパッケージについて


gridExtraパッケージのgrid.arrange関数は複数のグラフを並べて1つのグラフにしてくれます。



gridExtraパッケージを一度も使ったことがなければインストールします。
install.packages("gridExtra")
既にインストールしていればlibrary関数で呼び出します。
library(gridExtra) 



3.基本的な使い方

grid.arrange(グラフ1, グラフ2, ...)とつなげるだけです。そうすると縦に並びます。

grid.arrange(p_1, p_2)
スクリーンショット 2019-08-24 1.13.21



4.行数、列数の指定

行数と列数を指定することもできます。

grid.arrange(p_1, p_3, ncol = 1)
ncol = 1は横には1つ並べるという意味になります(何もつけないとこれになる)。
スクリーンショット 2019-08-27 7.17.26



grid.arrange(p_1, p_3, ncol = 2)
ncol = 2は横に2つ並べるとなります。
縦には制限なく並びます。

スクリーンショット 2019-08-27 7.17.34




grid.arrange(p_1, p_2, p_3, ncol = 2, nrow = 2)
ncol = 2は横に2つ並べる、nrow = 2は縦に2つ並べるという意味になります。
スクリーンショット 2019-08-27 7.17.45






5.大きさの比率を変える

縦と横の比率を変えることもできます。

横の比率を指定するwidths =と縦の比率を指定するheights =があります。
また1:2というように2つの数を指定する必要がありますので、width = c(1, 2)のように指定します。
もし横に3つ並べるならwidth = c(1, 3, 2)のように3つ数を指定します。

grid.arrange(p_1, p_2, p_3, ncol = 2, nrow = 2, widths = c(2, 1), heights = c(2,3))

スクリーンショット 2019-08-28 7.51.45





6.自分でレイアウトを作る

さらに細かいレイアウトも可能です。この方法は以下のサイトを参考にさせていただきました。




①自分でレイアウトを作る

3パターンレイアウトを作ってみました。
スクリーンショット 2019-08-28 21.55.43


ポイントはmatrix型にすることです。rbind関数c関数で縦につなぎます。
layout1 <- 
rbind(c(1, 2), c(1, 3)) layout2 <-
rbind(c(1, 3), c(2, 3)) layout3 <-
rbind(c(1, 2), c(3, 3))



②関数で作ったレイアウトを指定する

作ったレイアウトを指定するにはlayout_matrix = を指定します。
加えてwidths =heights =で微調整しています。


レイアウト1
grid.arrange(p_1, p_2, p_3, layout_matrix = layout1, widths = c(1, 3), heights = c(1, 2.5))
スクリーンショット 2019-08-28 22.00.35


レイアウト2
grid.arrange(p_1, p_2, p_3, layout_matrix = layout2, widths = c(1, 2))
スクリーンショット 2019-08-28 22.00.49



レイアウト3
grid.arrange(p_1, p_2, p_3, layout_matrix = layout3, heights = c(1, 2))
スクリーンショット 2019-08-28 22.01.01


7.まとめ

今回はパッケージを使って複数のグラフを1つにまとめる方法を紹介しました。

工夫次第でいろいろな見せ方ができます。gridExtraは便利なパッケージですのでぜひ試してみてください。










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

【3-8】ggplot2で折れ線グラフを作るgeom_line関数

【3-9】ggplot2でヒートマップを作るgeom_tile関数




今回は少し実用的な場面としてテストの結果を下位項目も含めてまとめてグラフに表示するを目指したいと思います。



以前仕事で1日で130個以上のグラフをExcelでコピペの手作業で作るという苦行をしたことがあるのですが、この方法で一気に作れるようになりました。

【3-4】Rのggplot2でヒストグラムを作るgeom_histogram関数でfacet_grid関数について説明しましたが、今回はfacet_wrap関数を紹介します。


また下位項目をまとめてグラフで表示するためにはデータハンドリングも必要になります。
データハンドリングについては2章で説明していますのでそちらもご参照ください。




1.使用するデータ

今回は【2-7】Excelの複数シートをRで一気に読み込むで取り込んだデータを使用します。
ただすぐに始められるように以下のコードを用意しました。
氏名、年齢、病院で使用するFIMという架空のデータです。
FIM18項目ありそれぞれ1〜7点で採点します。

またFIMには運動項目と認知項目というサブグループがあります。

食事〜階段までの13項目を運動項目(FIM_運動合計:13〜91点)
理解〜記憶までの5項目を認知項目(FIM_認知合計:5〜35点)
すべての合計をFIM_合計(18〜126点)

またFIMを3回計測し、sheetという列には1回目,2回目,3回目が入っています。

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

このデータからFIMの合計点と下位項目が1〜3回目でどのように変化したのかをグラフにしてみたいと思います。なお今回は棒グラフで平均を出します。


2.データハンドリング

【3-9】ggplot2でヒートマップを作るgeom_tile関数ではFIM_食事の項目だけを使いましたが、今回は全ての下位項目を使用します。

グラフ作成にあたり、以下をイメージしてデータハンドリングします。
・グラフを作る際、FIM_○○の"FIM_"はいらないので消したい
・sheetごと、各項目ごとの平均を出したい。そのためにはwideデータになっているdatをlongデータにする必要がある
・グラフに数値を表示するときに小数点が続くと見栄えが悪いので、小数点第1位まで表示したい

今回もtidyverseパッケージを使用します。

まだtidyverseパッケージを一度も使ったことがなければインストールします。
install.packages("tidyverse")
既にインストールしていればlibrary関数で呼び出します。
library(tidyverse) 

以下1例と解説です。

names(dat) <- str_remove(names(dat), "FIM_")

dat_stat <-
  dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
    group_by(項目, sheet) %>% 
    summarize(平均 = mean(点数), 標準偏差 = sd(点数)) %>% 
    mutate(平均 = round(平均, 1)) 



data.frameの名前を変更する方法

names関数を使うとdata.frameの列名をベクトルとして出してくれます。

names(dat)


そして直接変更するにはrename関数などありますが、同じ長さのベクトルを準備すると一括して入れ替えることができます。

names(dat) <- 同じ長さのベクトル


指定した文字列を消すstr_remove関数

str_remove関数は指定した文字を消す事ができます。

str_remove(ベクトル, "消したい文字列")

names(dat) <- str_remove(names(dat), "FIM_")


wideデータからlongデータに変える


wide, longデータについてはこちらの記事で紹介しています。




  dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
項目が五十音順にならないようにfactor_key = TRUEを指定します。



group_by関数とsummarize関数で集計する


項目とsheet毎に集計を行うにはgroup_by関数summarize関数を使います。



  dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
    group_by(項目, sheet) %>% 
    summarize(平均 = mean(点数), 標準偏差 = sd(点数)) 


四捨五入する

mutate関数round関数を使って平均の値を四捨五入します。




dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
    group_by(項目, sheet) %>% 
    summarize(平均 = mean(点数), 標準偏差 = sd(点数)) %>% 
    mutate(平均 = round(平均, 1)) 


まとめると最初のコードになります。

names(dat) <- str_remove(names(dat), "FIM_")

dat_stat <-
  dat %>% 
    gather(key = 項目, value = 点数, 食事:合計, factor_key = TRUE) %>% 
    group_by(項目, sheet) %>% 
    summarize(平均 = mean(点数), 標準偏差 = sd(点数)) %>% 
    mutate(平均 = round(平均, 1)) 


3.棒グラフを作成する

棒グラフを作るにはgeom_bar関数を使います。
棒グラフに数値を乗せる方法も紹介しています。





macの日本語文字化け対策にヒラギノ角ゴ Pro W3 ("HiraKakuPro-W3"を使っています。
windowの場合はエラーが出るかもしれませんのでtheme_gray(base_family = "HiraKakuPro-W3") +をの色をつけた箇所を消してください。



facet_wrapでグループ毎のグラフをまとめて作る

そしてグループ毎にグラフを作るにはfacet_wrap関数を使います。

facet_wrap( ~ グループ)

ggplot() +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(data = dat_stat, aes(x = sheet, y = 平均, fill = sheet), stat = "identity") +
  facet_wrap( ~ 項目)

スクリーンショット 2019-08-24 1.07.00


これで項目ごとのグラフができました。しかし気になる点があります。

facet_wrapはそのままだと軸が固定されています。
合計と各項目に点数差がありすぎて、各項目の点数の差がわかりません。


facet_wrapの軸をグループ毎に変更する

軸をグループ毎に帰るにはscales = "free"を追加します。

ggplot() +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(data = dat_stat, aes(x = sheet, y = 平均, fill = sheet), stat = "identity") +
  facet_wrap( ~ 項目, scales = "free")

スクリーンショット 2019-08-24 1.07.14


ただこれも1つ問題があります。
グラフ自体は変化しているように見えるのですが、それぞれの軸が違うのでグループ毎の比較ができません。


4.3種類のグラフに分けて保存する

全てのグラフをまとめてしまうとわかりにくいのでy軸のサイズを考慮して次の3種類に分けてグラフを作成してみます。

・合計
・運動項目合計, 認知項目合計
・下位項目

そのためにはdat_statからそれぞれを抽出してグラフを作成する必要があります。

・filter関数を使い抽出し、そのまま %>% でグラフ作成まで行ってみます。
・datから %>% でつないでggplot() + 〜と直接つなげるとdata = datを省略できます。
このようにするとdat_statのデータだけで完結します(dat_stat_合計みたいな変数を作らなくて済む)
下のコードの中にはdata = datが入っていないことを確認してみてください

・x軸の「sheet」とy軸の「平均」はいらないのでlabs関数で消します

・棒グラフはx軸の名前と凡例が同じなので凡例を消します
凡例を消すにはguides(fill = "none")を追加します

・facet_wrapでは軸を固定するためscales = "free"は追加しません

そしてfilter()の列以外は全部同じなことにも注目してください。
filter関数については【2-4】で紹介しています。



p_1:合計だけのグラフ
p_1 <-
dat_stat %>% 
  filter(項目 == "合計") %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")
スクリーンショット 2019-08-24 1.07.31


p_2:運動項目合計と認知項目合計のグラフ
p_2 <-
dat_stat %>% 
  filter(項目 %in% c("運動合計", "認知合計")) %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")
スクリーンショット 2019-08-24 1.07.41


p_3:下位項目のグラフ
p_3 <-
dat_stat %>% 
  filter(!項目 %in% c("運動合計", "認知合計", "合計")) %>% 
  ggplot(aes(x = sheet, y = 平均)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_bar(aes(fill = sheet), stat = "identity") +
  geom_text(aes(label = 平均), position = position_stack(vjust = 0.5)) +
  facet_wrap( ~ 項目) +
  labs(x = "", y = "") +
  guides(fill = "none")
スクリーンショット 2019-08-24 1.07.55



5.まとめ

今回はfacet_wrapでグループ毎のグラフを作る方法を紹介しました。
facet_wrapはグループの違いをみるのに非常に便利です。
ただ合計と下位項目が入っているデータだと軸の問題が出ますので注意が必要です。

今回作った3種類のグラフを組み合わせるためのgridExtraパッケージがあり次回紹介します。










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

【3-8】ggplot2で折れ線グラフを作るgeom_line関数



今回はヒートマップを紹介します。



ヒートマップはx軸,y軸だけでなくタイルの色で3次元的な表現ができます。
ヒートマップといえば天気アプリの雨雲予報などでも見られますが、今回は集計したデータを折れ線グラフとヒートマップで比べてみるとどうなるかをRのコードを書きながら紹介したいと思います。


1.使用するデータ

今回は【2-7】Excelの複数シートをRで一気に読み込むで取り込んだデータを使用します。
ただすぐに始められるように以下のコードを用意しました。
氏名、年齢、病院で使用するFIMという架空のデータです。
FIM18項目ありそれぞれ1〜7点で採点します(合計18〜126点)。
またFIMを3回計測し、sheetという列には1回目,2回目,3回目が入っています。

url <- "https://github.com/mitti1210/myblog/blob/master/fim.csv?raw=true"

dat <- read.csv(url)


2.データハンドリング

今回はFIMの中でもFIM_食事のデータだけを使います。
dat_eat:datから氏名,sheet,FIM_食事の列だけを抜き出す
dat_eat_summarize:dat_eatからsheet毎の平均を集計
dat_eat_stat:1〜7点がそれぞれ何人ずついるかカウント


今回はselect関数, rename関数, group_by関数, summarize関数, n関数, この後グラフ作成で使うggplot2関数は全てtidyverseパッケージに含まれます。

まだtidyverseパッケージを一度も使ったことがなければインストールします。
install.packages("tidyverse")
既にインストールしていればlibrary関数で呼び出します。
library(tidyverse) 

もしデータハンドリングを練習しているところであれば下のコードをみながら作成してみてください。

dat_eat <- 
dat %>%
select(氏名, sheet, FIM_食事) 

dat_eat_summarize <-
dat_eat %>%
group_by(sheet) %>%
summarize(平均 = mean(食事), 項目 = "食事")

dat_eat_stat <-
dat %>%
select(FIM_食事, sheet) %>%
group_by(sheet, FIM_食事) %>%
summarize(n = n())
 
スクリーンショット 2019-08-23 2.47.56
ポイントは以下2つです。
dat_eat_summarizeでは折れ線グラフを作成するのに項目という列を追加しました。
dat_eat_statで個数を数える場合はn()を使います。()の中は何も入れません。

まだなれない場合は下のリンクを参照してください。

【2-4】Rで指定した列や行だけを取り出すselect関数、slice関数、filter関数を紹介します

【2-6】Rでgroup_by関数とsummarize関数を使ってグラフ作成に必要な統計量(平均や標準偏差など)を求める

【演習2】データハンドリングの基礎を復習します


3.折れ線グラフを作る

まずは折れ線グラフを作ってみます。
折れ線グラフはgeom_line関数、数値を入れる場合はgeom_text関数です。

参照:【3-8】ggplot2で折れ線グラフを作るgeom_line関数


平均の折れ線グラフ

まずdat_eat_summarizeを使って平均の折れ線グラフを作ります。
ylim関数はy軸の最大値と最小値を設定します。

ggplot() +

theme_classic(base_family = "HiraKakuPro-W3") +
geom_line(data = dat_eat_summarize, aes(x = sheet, y = 平均, group = 項目), color = "red") +
geom_text(data = dat_eat_summarize, aes(x = sheet, y = 平均, label = 平均), vjust = -1, color = "red") +
ylim(0, 7)
スクリーンショット 2019-08-23 2.07.44



実際の生データと平均を組み合わせる

要約としてはこれでもいいですが、実際のデータも確認してみたいと思います。

実際のデータはdat_eatにあるので使います。group = 氏名 にすると患者毎の折れ線グラフを作ることができます。またcolor = "gray" として薄くしたほうが平均の線が目立ちます。

ggplot() +

theme_classic(base_family = "HiraKakuPro-W3") +
geom_line(data = dat_eat, aes(x = sheet, y = FIM_食事, group = 氏名), color = "gray") +
geom_line(data = dat_eat_summarize, aes(x = sheet, y = 平均, group = 項目), color = "red") +
geom_text(data = dat_eat_summarize, aes(x = sheet, y = 平均, label = 平均), vjust = -1, color = "red")
 
スクリーンショット 2019-08-23 2.07.51



4.ヒートマップを作る

上の折れ線グラフもいいのですが、線が重なっているので数字が多いのか少ないのかわかりません。
そのため次はヒートマップを作成してみます。

ヒートマップはgeom_tile関数、またはgeom_raster関数です。

geom_tile関数でヒートマップの色を指定するのにfillを指定します。
使うデータはdat_eat_stat, x軸にsheet(1〜3回目) , y軸にFIM_食事(1〜7点), 色をn(カウント数)としたいので以下になります。

geom_tile(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, fill = n)) 

ggplot() +
	
theme_gray(base_family = "HiraKakuPro-W3") +
geom_tile(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, fill = n))
 
スクリーンショット 2019-08-23 2.07.59



5.タイルの色を変える

タイルの色を変えるにはscale_fill_gradientn関数を使います。
折れ線グラフの線の色を変える時はscale_color_gradientn関数でした。
今回は中の色を指定するのでcolorではなくfillになっています。
colours =で2色指定するとグラデーションができます。
3色以上指定すると中間の色も指定できます。

ggplot(data = dat_eat_stat) +

theme_gray(base_family = "HiraKakuPro-W3") +
geom_tile(aes(x = sheet, y = FIM_食事, fill = n)) +
scale_fill_gradientn(colours = c("yellow", "red"))
スクリーンショット 2019-08-23 2.08.06

すると1→3回目になるにつれて7点が増えていることがわかります。


6.ヒートマップに数値を加える

ヒートマップで傾向はつかめますが数値も欲しいところです。
棒グラフや折れ線グラフの時と同様にgeom_text関数を使います。

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

【3-8】ggplot2で折れ線グラフを作るgeom_line関数


ggplot() +

theme_gray(base_family = "HiraKakuPro-W3") +
geom_tile(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, fill = n)) +
scale_fill_gradientn(colours = c("yellow", "red")) +
geom_text(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, label = n))
 

よく見るとgeom_tileもgeom_textも"data = dat_eat_stat, aes(x = sheet, y = FIM_食事" までは同じなので下のようにまとめることができます。
ggplot(data = dat_eat_stat, aes(x = sheet, y = FIM_食事)) +
  theme_gray(base_family = "HiraKakuPro-W3") +
  geom_tile(aes(fill = n)) +
  scale_fill_gradientn(colours = c("yellow", "red")) +
  geom_text(aes(label = n)) 
スクリーンショット 2019-08-23 2.08.14


数値が入ったことで見やすくなりました。



7.ヒートマップに折れ線グラフを組み合わせる

更にヒートマップと折れ線グラフを重ねてみます。
ポイントは下に書いたコードが上に配置されます。

1番上:数値
2番目:折れ線グラフ
3番目:ヒートマップ

順番が大事です。

ggplot() +

theme_gray(base_family = "HiraKakuPro-W3") +
geom_tile(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, fill = n)) +
scale_fill_gradientn(colours = c("yellow", "red")) +
geom_line(data = dat_eat, aes(x = sheet, y = FIM_食事, group = 氏名), color = "gray") +
geom_text(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, label = n))
 
スクリーンショット 2019-08-23 2.08.21


これで十分ではありませんが、数値の変化も少し追えるようになりました。


8.全部のグラフを重ねる

過剰かもしれませんが、上のグラフに平均の折れ線グラフも加えてみます。
順番に注意してください。

ggplot() +

theme_gray(base_family = "HiraKakuPro-W3") +
geom_tile(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, fill = n)) +
scale_fill_gradientn(colours = c("yellow", "red")) +
geom_line(data = dat_eat, aes(x = sheet, y = 食事, group = 氏名), color = "gray") +
geom_line(data = dat_eat_summarize, aes(x = sheet, y = 平均, group = 項目), color = "red", size = 1.5) +
geom_text(data = dat_eat_stat, aes(x = sheet, y = FIM_食事, label = n)) +
geom_text(data = dat_eat_summarize, aes(x = sheet, y = 平均, label = 平均), vjust = -1, color = "black")
 
スクリーンショット 2019-08-23 2.08.28




9.まとめ

今回はヒートマップを紹介しました。
難しそうに感じますが、x軸とy軸にfillを加えるだけでヒートマップができてしまいます。
いろいろアイデアを試してみるとggplot2やその前のデータハンドリングの理解にもつながりますので、3章の他のグラフも見ながらグラフ作成に挑戦してみてください。



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


↑このページのトップヘ