【お知らせ】来週 10月23日(金)は休講です。 担当教員の研究出張のため休講となり,第4回以降を1週ずつ繰り下げます。 次回の第4回「データの可視化(2)」は 10月30日(金) です。
空く2週間のあいだに,下の宿題(.R
ファイルの保存)を済ませておいてください。
ggplot2 の基本的な考え方(レイヤー構造)を理解するaes()
による変数の対応づけと,見た目の固定指定を区別できる本題に入る前に,前回の宿題(演習1〜4を1つの .R
ファイルに保存する)を確認します。
まず,保存した .R
ファイルを開いてください。 開けたら,上から順に実行してみます。
ここでつまずく人が毎年います。原因はたいてい次の2つなので,先に片づけておきます。
どちらも「ファイルがどこに行ったか分からない」「前に書いたコードが動かない」の正体です。
解答例:第2回 演習の模範解答(
.Rファイル) 自分の答えと見比べてください。追加問題(体重65kgのBMI)と,install.packages()とlibrary()の違いも入っています。
ファイルが見つからない人は,保存先が「デスクトップ」や「ダウンロード」になっています。
File → Recent Files
から開き直せることが多いので,まず試してください。
開けたら,この授業用のフォルダに置き直します。その整え方がプロジェクトです。
プロジェクトとは,1つのフォルダを「分析のひとまとまり」としてRStudioに覚えさせる仕組みです。
作ると,そのフォルダの中に ○○.Rproj
というファイルが1つできます。これがプロジェクトの本体です。
プロジェクトを使うと,次の4つが自動で片づきます。
| 困ること | プロジェクトを使うと |
|---|---|
| ファイルを読み込むとき,長いパスを書かないといけない | そのフォルダが自動で作業場所になるので,read.csv("data/kekka.csv")
のように短く書ける |
setwd("C:/Users/...") を毎回書き換えている |
書かなくてよくなる(setwd()
は使わないのが現代的な流儀です) |
| 別の課題のデータや変数が混ざる | 分析ごとにフォルダが分かれ,開いていたタブもそのまま復元される |
| USBや別のPCに移したらパスが全部壊れた | フォルダごと移動してもそのまま動く |
作り方
File → New Project...New Directory → New ProjectDirectory name
にフォルダ名,Create project as subdirectory of
に置き場所を指定Create Projectこの授業では,たとえば kodo-keiryo
という名前のプロジェクトを1つ作り, その中に回ごとの .R
ファイルを置いていくとよいでしょう。
前回保存したファイルも,このフォルダに移しておいてください。
フォルダ名と置き場所の注意
- 名前に日本語・スペースを使わない(
第3回 課題ではなくweek03のように)- OneDrive / iCloud の同期フォルダは避ける。同期とRの書き込みがぶつかって保存に失敗することがあります
すでにフォルダがある人は,手順2で
Existing Directoryを選べば,そのフォルダをプロジェクトにできます。
開き方:.Rproj
ファイルをダブルクリックします。
RStudioの右上に今開いているプロジェクト名が出ているので,そこから切り替えることもできます。
いまどこで作業しているか確かめたいときは getwd()
を実行します。
RStudioを閉じようとすると保存を聞かれますが,聞かれているものが2種類あり,答えが逆になります。
① スクリプト(.R ファイル)の保存 →
必ず保存する
タブの名前が赤くなっていたり *
が付いていたら未保存です。これはあなたが書いたコードそのもの,つまり成果物です。Ctrl + S(Macは
Cmd + S)で保存してください。
② 「Save workspace image to ~/.RData?」 →
保存しなくてよい(Don't Save)
RStudioを閉じるときに出てくる,あの英語の確認画面です。これは
「いま変数に入っているデータを,次回も残しておきますか」という質問です。
Save / Don't Save / Cancel
の3択なら,Don't Save
を選んでください。
| 中身 | 答え | |
|---|---|---|
.R ファイル |
書いたコード | 保存する |
.RData(ワークスペース) |
実行してできた変数・データ | 保存しなくてよい |
.Rhistory |
コンソールに打った履歴 | 保存しなくてよい |
なぜ保存しなくてよいのか。 コードが残っていれば,変数は実行し直せば作り直せます。 むしろ保存すると困ることが起きます。
前回の古い変数が残ったまま次回が始まるので, コードを直したのに結果が変わらない,逆に コードを消したのに動いてしまう(消したはずの変数がまだメモリにいる)ということが起きます。 そうなると,そのコードを他の人に渡しても動きません。
「まっさらな状態から上から順に実行すれば,同じ結果になる」という状態を保つこと。 これが分析の再現性で,この授業でずっと大事にしてほしい考え方です。
毎回聞かれないようにする設定(おすすめ)
Tools → Global Options... →
GeneralSave workspace to .RData on exit: を
Never にするRestore .RData into workspace at startup
のチェックを外すこれで聞かれなくなり,起動のたびにまっさらな状態から始まります。
例外:計算に何十分もかかった結果だけは,残したいことがあります。 そのときはワークスペース全体ではなく,必要なものだけを明示的に保存します。
ggplot2
は,Rで最も広く使われているグラフ作成パッケージです。
ggplot2では,グラフをレイヤー(層)を重ねるように作ります。
| 要素 | 説明 |
|---|---|
ggplot() |
キャンバスを準備する |
aes() |
変数とグラフ要素のマッピングを指定 |
geom_xxx() |
グラフの種類(散布図・棒グラフなど) |
上の「データ」「x軸の変数」「
geom_xxx()」は,構造を示すための仮の書き方です。 そのまま打っても動きません。実際の名前に置き換えて使います。
今日は R に最初から入っているデータセット iris
を使います。
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100
## 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300
## Median :5.800 Median :3.000 Median :4.350 Median :1.300
## Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
## 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
## Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
## Species
## setosa :50
## versicolor:50
## virginica :50
##
##
##
前回はベクトル(数値が一列に並んだもの)を扱いました。今日からは表の形をしたデータを使います。
irisは 150行・5列のデータフレームです。
- 1行が,1本の花の観測です。全部で150本
- 1列が,測定項目または種です
| 列名 | 内容 | 単位 |
|---|---|---|
Sepal.Length |
がく片の長さ | cm |
Sepal.Width |
がく片の幅 | cm |
Petal.Length |
花びらの長さ | cm |
Petal.Width |
花びらの幅 | cm |
Species |
種(setosa / versicolor / virginica) | — |
3つの種がそれぞれ50本ずつ入っています。
この「1行=1つの観測」という構造が分かると,散布図の点1つが何を表すかが見えてきます。点1つが,1本の花です。
str()の出力は情報が多いですが,いま読み取るのは2つだけです。 「何行・何列か」と,「数値の列と,種を表すカテゴリの列があること」です。 記号をすべて覚える必要はありません。
aes() の中と外では意味が違うここが今日いちばん間違えやすいところです。
| 書く場所 | 意味 | 例 |
|---|---|---|
aes() の中 |
データの値を,見た目に対応づける | aes(color = Species) → 種ごとに色が変わる |
aes() の外(geom_
の中) |
見た目を1つに固定する | geom_point(color = "blue") → 全部の点が青 |
実際に比べてみます。
# 全部の点を青にする(aes の外)
ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length)) +
geom_point(color = "blue")
aes(color = "blue")と書いてはいけません。aes()の中に書いた"blue"は色の指定ではなく,1つのカテゴリの名前として扱われます。 そのため青にはならず,全部の点が同じ色(既定の赤っぽい色)になり,凡例にblueと表示されます。
もう1つ覚えておくと迷いません。
列名には引用符を付けない。色名やタイトルなどの文字列には引用符を付ける。
aes(x = Petal.Length)… 列名なので引用符なしlabs(title = "花びらの長さ")… 文字列なので引用符あり
散布図では x と y
の両方を指定しましたが,ここでは x
だけです。縦軸を書いていません。
ヒストグラムは,数値を区間に分けて,その区間に入った観測の個数を自動で数えます。 だから縦軸は度数(個数)になります。自分で指定する必要はありません。
実行すると,次のようなメッセージが出ることがあります。
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
これは失敗ではありません。 「区間の数を標準の30にしました。自分で決めることもできますよ」という案内です。
ggplot(data = iris, aes(x = Sepal.Length)) +
geom_histogram(binwidth = 0.3, fill = "steelblue", color = "white")binwidth = 0.3 は,がく片の長さを 0.3cm
刻みの区間に分けるという指定です。
1つの幅だけ見て判断しないでください。 幅を変えると印象が変わります。 いくつかの幅を試して,山の数や偏りがどれくらい変わるかを見比べてください。 幅の取り方で山が1つに見えたり2つに見えたりします。 自分の言いたい結論に都合のよい幅だけを選ばないこと, そして論文やレポートではどの幅を使ったかを書くことが大事です。
なお fill = "steelblue" と color = "white"
は aes()
の外にあるので,全部の棒を同じ色にする固定指定です。
種ごとのデータ件数を棒グラフで表示します。
ここでも y
を指定していません。geom_bar()
は,カテゴリごとの観測数を自動で数えます。
3本の棒がすべて同じ高さ(50)になりました。これは
iris に各種50本ずつ入っているからです。
「3種が同じ大きさ」とか「自然界に同じ割合でいる」という意味ではありません。
すでに計算してある数値を棒の高さにしたいとき(例:種ごとの平均値)は,
geom_bar()ではなくgeom_col()を使います。 「数えるのがgeom_bar(),与えられた値を描くのがgeom_col()」と覚えてください。
グループ間の分布を比較するのに便利です。
この図は,次の部品でできています。
| 部品 | 表しているもの |
|---|---|
| 箱の下端 | 第1四分位数(下から25%の位置) |
| 箱の中の線 | 中央値(真ん中の値) |
| 箱の上端 | 第3四分位数(下から75%の位置) |
| ひげ | 箱から離れすぎていない範囲の,最小値・最大値 |
| ひげの外の点 | ひげの範囲から外れた観測 |
つまり箱の中に,データの真ん中半分(50%)が入っています。
箱が縦に長い=真ん中50%のばらつきが大きい。短い=そろっている。 箱の高さが表しているのは \(IQR\),つまり中央50%の広がりです。 分布全体のばらつきは,箱の高さだけでは分かりません(ひげと外側の点も見ること)。 また箱の高さは「件数」ではありません。どの種も50本ずつあります。
ひげについて,もう少し正確に書いておきます。
ひげは必ずしも最小値・最大値まで伸びるわけではありません。 箱の高さ(第3四分位数 − 第1四分位数)を \(IQR\) として, \[[\,Q_1 - 1.5 \times IQR,\ \ Q_3 + 1.5 \times IQR\,]\] という範囲を考えます。ひげは,この範囲に入っている観測のうちの最小値・最大値まで伸びます。 それより外側の観測は,点として個別に描かれます。
外側の点を見つけても,「入力ミスだ」「消すべきだ」と決めつけないでください。 本当に珍しい個体かもしれませんし,重要な発見かもしれません。 まずは「そういう観測がある」と認識するところまでです。
ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
geom_point() +
labs(
title = "がく片の長さと花びらの長さの関係",
x = "がく片の長さ (cm)",
y = "花びらの長さ (cm)",
color = "種"
)| 引数 | 役割 | 例 |
|---|---|---|
x |
x軸の変数 | x = Sepal.Length |
y |
y軸の変数 | y = Petal.Length |
color |
色(線・点) | color = Species |
fill |
塗りつぶし色 | fill = Species |
size |
点の大きさ | size = Petal.Width |
shape |
点の形 | shape = Species |
iris データを使って,Petal.Length(x軸)と
Petal.Width(y軸)の 散布図を作成し,Species
で色分けしてください。
図ができたら,次の2つに答えてください。回答は #
を付けてコメントで書きます。
点が150個より少なく見えても,データが消えたわけではありません。 同じ位置に複数の花が重なっているだけです(150本の花に対し,長さと幅の組合せは102通りしかありません)。
Petal.Width
のヒストグラムを作成し,適切なタイトルと軸ラベルを付けてください。
binwidth は
0.2,色は好きなものを選んで構いません。
色の正解は1つではありません。
ggplot(data = iris, aes(x = ___)) +
geom_histogram(binwidth = ___, fill = "___", color = "white") +
labs(title = "___", x = "___", y = "___")確認してほしいのは次の3点です。
Petal.Width を使っているか余裕があれば:
binwidthを 0.1,0.2,0.4 に変えて,見え方がどう変わるか1文で書いてみてください。
種(Species)ごとに Petal.Length
の分布を箱ひげ図で比較してください。 fill = Species
を追加してカラフルにしてみましょう。
図ができたら,次に答えてください。
setosa の箱は,他の2種より縦に短くなります。 これは件数が少ないからではありません(どの種も50本です)。 第1四分位数から第3四分位数までの幅が狭い,つまり真ん中50%のばらつきが小さいということです。
演習1〜3の解答例を置いてあります。自分で解いたあとに見てください。
ブラウザで中身が表示されます。保存するときは右クリック →「リンク先を別名で保存」。 RStudioで開いて,全選択して
Ctrl + Enterで実行して確かめてください。
ggplot2 はレイヤーを重ねてグラフを作るggplot(data = ..., aes(...)) + geom_xxx()aes()
の中は「データを見た目に対応づける」,外は「見た目を固定する」geom_point()),ヒストグラム(geom_histogram()),棒グラフ(geom_bar()),箱ひげ図(geom_boxplot())を作れるようになったlabs() でタイトル・軸ラベルを追加できるlibrary(tidyverse)
と演習1〜3の作図コードを,1つの .R
ファイルにまとめて保存する
Ctrl + S /
Cmd + S)とどこに置くかは, 第2回の「まずスクリプトを1つ作る」を見てください.R
ファイルを開き直し,上から順にコードを実行して3つの図が表示できることCtrl + A)してから
Ctrl + Enter(Mac は Cmd + A →
Cmd + Enter)
でまとめて実行できます。1行ずつ実行する必要はありませんsource("ファイル名.R")
でまとめて実行すると図が表示されません。
まとめて実行したい人は p1 <- ggplot(...) + ...
と変数に入れ,print(p1) を書いてください