第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章の他のグラフも見ながらグラフ作成に挑戦してみてください。



職場ではExcelでデータ集計しているという職場も多いと思います。

その中でタブに1回目,2回目,,,や1月,2月,,,というように同じデータ形式を複数シートで管理する場合もあるかもしれません。

同じ形式で複数シートにまたがるデータをRで一度に読み込む方法を紹介します。

今回はfim.xlsx という架空のファイルを準備していますが、記事を見ながらご自身でExcelファイルを作ってみても大丈夫です。


(注意)
今回の記事はr-wakalang」でのアドバイスを参考にさせていただきました。
自分も別の方法でしていたのですが、あまりにもスマートな方法なので今回の方法に切り替えました。





1.前提

まずこの方法ができるためにはいくつか前提が必要です。

・全てのシートが同じ形式

シート毎に列名やいろいろなものがバラバラでは読み込めません。
フォーマットはちゃんと決めましょう。もしくはシートを複数選択しまとめて処理をしましょう。
cntr(macではcommand)を押しながらクリックするとシートを複数選択→一括処理ができます。

・セル結合が無い

Excelでセル結合をすると見栄えは良くなったように感じますが、集計を行う時はExcelでもRでも非常に困る場合が多いです!!!!!

・列のタイトルが複数行にまたいでいる

例えば病院で下位項目があるテストを記録すると列名が複数行にまたぐ場合があります。

そしてこのような場合、上の行はだいたいセル結合されています・・・


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



2.Excelでの対策

ただ上司にセル結合+列名を2行にしないと減給だ!!!と脅される場合もあるかもしれません。

自分ならもう一列Rで列名読み込むための行を作るという回避策を用意します。
そのときに役に立つのがExcelの&です。

ポイントは以下の3つです。
①集計に使うシートを全て選択し一括処理の状態にする
② 実際のデータ入力する列の1つ上の行に挿入する(ここでは3行目)

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



③ A,B,C列は実質1行なので を使う。
④ D列以降は複数行にまたがるため でつなげる
⑤ D1は絶対参照($)をつけるとコピーで失敗しない

(下の図ではわかりやすいように数式を表示しています)

スクリーンショット 2019-08-21 0.18.00


実際の見え方はこうなります。
スクリーンショット 2019-08-20 23.05.24


⑥D3をコピー→右の空いた所全てを選択し貼り付け

⑤誰かに邪魔されないように3行目を非表示にすれば完成!


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

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




3.Excelの&について

D1&D2とするとD1の値とD2の値を文字列としてくっつけてくれます

D1はFIMD2は食事なので、=D1&D2FIM食事となります。

今回はFIMと食事の間に_をはさみます。
(- * , . )などの記号や空白はRで読み込んだ際に不都合が出ることがあります。
そのため間に挟む記号は _ (アンダーバー)をおすすめします。

_のような文字列を&で繋げる場合は"(ダブルクォーテーション)ではさみます。

よって=D1&"_"&D2 は FIM_食事となります。


4.Excelの相対参照と絶対参照について

D3にある=D1&"_"&D2をコピーしてE3に貼り付けるとE1&"_"&E2となります。
他にもD3を選択→セル右下のちっちゃい■をクリックし右にビーーーーーーっと伸ばすと一気にコピーできます。
Excelはコピーした位置関係を覚えてくれるのでこういった処理は非常に便利です。これを相対参照と言います。

しかしこの方法を使うと不都合が出ます。本来E3セルにはD1&"_"&E2と1行目は動かずに2行目を動かしたいところです。
この動かさないを指定するのが$(絶対参照)です。

$D1:左右にコピペしてもDの値は変わらない。上下にコピペすると1の値は変わる
D$1:左右にコピペするとDの値が変わる。上下にコピペしても1の値は変わらない
$D$1:上下左右にコピペしてもD1の値は変わらない。

今回は横にコピペしてもずれてほしくないので、D3の計算式ではD1ではなく$D1もしくは$D$1とすれば上手くいきます。するとE3〜は一気にコピペ可能です。


5.Rへの読み込み

前置きが長くなりましたがいよいよRに取り込みます。

・プロジェクトを作成し、Excelデータも同じフォルダに置く

実際に分析を行う時は仕事1つ1つでプロジェクトを作ると管理が便利です。
プロジェクトについては【1-6】Rstudioのプロジェクトについて解説しますで紹介しています。


・パッケージを読み込む

パッケージに関しては【1-7】Rで使うパッケージのインストールについて紹介します。をご参照ください。

Excelを読み込むにはいくつかあるのですが今回はreadxlパッケージとpurrrパッケージを使います。
purrrパッケージは2章で使ってきたtidyverseパッケージに含まれています。


#tidyverseパッケージをインストールしていなければインストール。
install.packages("
readxl
")
install.packages("tidyverse")

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


・実際に読み込む

file <- "fim.xlsx"
sheets <- excel_sheets(file)
dat <- 
  sheets %>% 
  map_dfr( ~ read_excel(file, skip = 2, sheet = .x) %>% 
             mutate(sheet = .x)) 
これで全てのタブを読み込むことができます。



(以下補足)
6.何をしているのか?

1つずつ説明していきます。

ファイル名を指定する

まずfileという変数(別に名前はfileでなくても良い)にExcelのファイルを指定します。
そうすれば後のread_excel関数で楽ができます。

シートの名前リストを作る

Excelから複数シートを読み込むにはシートのリストが必要です。

readxlパッケージのexcel_sheet関数がまさにそれです。

sheets <- excel_sheets(file)
スクリーンショット 2019-08-21 19.47.36



これでsheetsという変数にタブの名前が入りました。

今回はこのままで問題ありませんが、Excelの中には「基本情報」や「選択項目」など必要ないタブもあるかもしれません。
その時はsheetsから間引きます。間引く時は【1-12】Rで特定の条件にあう要素を抜き出す方法で紹介した [ ] が使えます。

シートは名前だけでなく、左から1,2,,,,と自動的に番号が振り分けられています。
いらないシート番号がわかっている時はいらない番号だけ指定すればいいです。
(もちろんいる番号だけ指定してもいいです)

sheets <- excel_sheets(file)

sheets <- sheets[-2]
スクリーンショット 2019-08-21 19.52.58


シートの数が多すぎてシート番号がもはや分からない時は  %in% でシート名を指定することができます。
sheets <- excel_sheets(file) 
sheets <- sheets[!sheets %in% "2回目"]
スクリーンショット 2019-08-21 19.53.16


1つだけExcelを読み込む時のread_excel

1つだけExcelを読み込む関数はいくつかあるのですが、今回はread_excel関数を使います。
read_excel関数はxls,xlsxどちらも読み込むことができます。

read_excel(file, skip = 2, sheet = "1回目") 
基本の形は read_excel("Excelファイル", sheet = "シート名") となります。
そしてskip=を使うと最初の数行を飛ばして読み込むことができ、今までの対策が活きてきます。
skip=2で1,2行目をskipし3行目を列名、4行目以降をデータとして読み込むことができます。

スクリーンショット 2019-08-22 0.27.55



繰り返し処理でdata.frameにデータを追加するmap_dfr関数

map_dfr関数はExcelの複数のシートやフォルダの中にあるcsvファイルをまとめて読み込むのに便利です。
ちなみにmap(繰り返し処理)、df(データフレーム)、r(縦につなげる)でmap_dfrです。
横につなげる時はmap_dfc関数ですがここでは目的に合致しません。


最初に.xにあたる繰り返すためのリストを用意して%>%でつなぎます。
ここでは"1回目"→"2回目"→"3回目"としたいわけです。そこで先程のsheets <- excel_sheets(file)でそれを作りました。


そして先程紹介したread_excel関数を使います。最初に ~(チルダ)を入れることがポイントです。


加えて足した後にこのデータがどのシートかわかる(集計する)ためにmutate関数をつかってsheet(別の名前でもいい)という列名を追加します。ここでも.xを使うことで"1回目", "2回目", "3回目"を追加してくれます。

スクリーンショット 2019-08-22 0.22.50



7.まとめ

今回はExcelで複数のシートを読み込む方法を紹介しました。
今までExcel使っていたけどRも使ってみたいなという方がいましたら練習と実用を兼ねている課題だと思いますのでぜひ挑戦してみてください。


8.参考にさせていただいたサイト

purrrを使ったExcelの読み込みはr-wakalangさんの質問を参考にさせていただきました。
それまではforを使っていたのですが、map_dfrはとても便利でした!
r-wakalangはRを使っている方は絶対におすすめです!





このサイトはRどころかプログラミング自体わからない状態からRの基本的な使い方がわかり、集計やグラフ作成、基本的な医療統計(もしかしたら機械学習の基礎)が使えることを目指しています。

自分はプログラミングの専門家でもありませんし、データサイエンティストとして生計を立てているわけでもありません。

病院に勤務している一理学療法士です。

ただ、日々業務をしながらデータ分析とかしてみたいんだけど、そもそも何からしたらいいのかわからない学会で統計が必要なんだけど全然わからないと感じている方は自分も含めいると思います。

そういった分析の専門家でない方に少しでも参考になる部分があり、もし興味が出てきたらこのサイトを卒業して、然るべき書籍や講義などステップアップしていただければ幸いです。



自分は2018年夏にRや統計を独学しようと思い、Edxで「HarvardX  Professional Certificate inData Science」を受講し修了しました。


スクリーンショット 2019-07-13 22.34.33


このサイトはそこで学んだことの自分への備忘録にもなります。

MITTI1210 on Twitter

Edxで「ハーバードX データサイエンスプロフェッショナルコース」受講中 ①Rの基礎 ②グラフの作り方 ③確率 ④推論とモデリング ⑤生産性ツール ⑥ラングリング(データ整理) ⑦線形回帰 ⑧機械学習 ⑨応用 全9回の講義。全て合格目指します。 https://t.co/SkfjzAH64w






サイトの内容はプログラム経験者や独学が得意な方にはくどく、必要な情報が全て載っていないとお叱りを受けると思います。ただ、プログラム未経験者だった自分が「このぐらい噛み砕いて説明してほしかった!」「まずはこんな順で教えてほしかった!」と感じたことを記事にしています


まずはイメージがしやすいこと、とりあえず動くことを念頭において記事を作成しています。情報を網羅するというより必要最低限の情報だけ伝え、必要になった場面で追加の情報が出てくるようにしたいと考えています。もしかしたら辞書的な使い方には向いていないかもしれません。多くの素晴らしいサイトや書籍がありますので、そちらもご参照ください。


そのため第1章から順に読むと徐々に知識が追加され、途中で復習できるよう構成しています。

途中で読んでわからないところは基本的に以前の記事に情報があるようにしているので、困った時は前の記事を確認してみてください!



第1章:Rの基本の「き」


Rって何?

【1-1】統計ソフトRで何ができるか説明してみる


Rのソフトについて

【1-2】RコマンダーやRStudioなどRのソフトにも色々あるので解説してみる

【1-3】Rのソフトはどれを使えばいいか?目的別チャートを作りました

【1-4】はじめてのRStudio。基本的な画面の説明をします

【1-5】Rコマンダーの基本的な画面の説明を行います

【1-6】Rstudioのプロジェクトについて解説します

【1-7】Rで使うパッケージのインストールについて紹介します。



Rの基本的な使い方について

【1-8】R の「変数」について説明します。

【1-9】医療統計をRで使うために必要な「データフレーム」にの考え方ついて

【1-11】Rで医療統計で必要なtable1を作るtableoneパッケージについて紹介します

【1-12】Rで特定の条件にあう要素を抜き出す方法

【演習1】R初心者が統計をかけるための前準備の流れを復習します


第2章:データを扱う

【2-1】Rのfor関数、apply関数を使ってまとめて標準偏差などの統計量を求める方法

【2-2】Rのmutate関数を使って列の追加や修正を行う

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



第3章:グラフを作る

【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パッケージ






その他



自己紹介

昨年(2018年)の振り返りと今年の目標


Qiita

ROC曲線とPR曲線の違いを混合行列と有病率から考えてみる

ggplot2で100%積み重ね棒グラフの真ん中に値を表示させたい

箱ひげ図の「ひげ」の上端と下端の値を知りたいので関数を自作した


Fukuoka.R

Fukuoka.R #14
Harvard Xについて解説しています。



Fukuoka.R #15
10点のテスト(順序尺度)の経時的変化をグラフ化するアイデアを載せています。
コードも載せていますが【3-9】ggplot2でヒートマップを作るgeom_tile関数で紹介しています。


↑このページのトップヘ