← 授業トップへ戻る


【お知らせ】来週 10月23日(金)は休講です。 担当教員の研究出張のため休講となり,第4回以降を1週ずつ繰り下げます。 次回の第4回「データの可視化(2)」は 10月30日(金) です。

空く2週間のあいだに,下の宿題(.R ファイルの保存)を済ませておいてください。


本日の目標

  1. ggplot2 の基本的な考え方(レイヤー構造)を理解する
  2. 散布図・ヒストグラム・棒グラフ・箱ひげ図を作成できる
  3. aes() による変数の対応づけと,見た目の固定指定を区別できる
  4. 作った図が何を表しているかを説明できる

0. 前回の宿題の確認:保存先と,終了するときの「保存」

本題に入る前に,前回の宿題(演習1〜4を1つの .R ファイルに保存する)を確認します。

まず,保存した .R ファイルを開いてください。 開けたら,上から順に実行してみます。 ここでつまずく人が毎年います。原因はたいてい次の2つなので,先に片づけておきます。 どちらも「ファイルがどこに行ったか分からない」「前に書いたコードが動かない」の正体です。

解答例:第2回 演習の模範解答(.R ファイル) 自分の答えと見比べてください。追加問題(体重65kgのBMI)と, install.packages() と library() の違いも入っています。

0-1. ファイルの保存先と,プロジェクト

ファイルが見つからない人は,保存先が「デスクトップ」や「ダウンロード」になっています。 File → Recent Files から開き直せることが多いので,まず試してください。 開けたら,この授業用のフォルダに置き直します。その整え方がプロジェクトです。

プロジェクトとは,1つのフォルダを「分析のひとまとまり」としてRStudioに覚えさせる仕組みです。 作ると,そのフォルダの中に ○○.Rproj というファイルが1つできます。これがプロジェクトの本体です。

プロジェクトを使うと,次の4つが自動で片づきます。

困ること プロジェクトを使うと
ファイルを読み込むとき,長いパスを書かないといけない そのフォルダが自動で作業場所になるので,read.csv("data/kekka.csv") のように短く書ける
setwd("C:/Users/...") を毎回書き換えている 書かなくてよくなる(setwd() は使わないのが現代的な流儀です)
別の課題のデータや変数が混ざる 分析ごとにフォルダが分かれ,開いていたタブもそのまま復元される
USBや別のPCに移したらパスが全部壊れた フォルダごと移動してもそのまま動く

作り方

  1. File → New Project...
  2. New Directory → New Project
  3. Directory name にフォルダ名,Create project as subdirectory of に置き場所を指定
  4. Create Project

この授業では,たとえば kodo-keiryo という名前のプロジェクトを1つ作り, その中に回ごとの .R ファイルを置いていくとよいでしょう。 前回保存したファイルも,このフォルダに移しておいてください。

フォルダ名と置き場所の注意

  • 名前に日本語・スペースを使わない(第3回 課題 ではなく week03 のように)
  • OneDrive / iCloud の同期フォルダは避ける。同期とRの書き込みがぶつかって保存に失敗することがあります

すでにフォルダがある人は,手順2で Existing Directory を選べば,そのフォルダをプロジェクトにできます。

開き方:.Rproj ファイルをダブルクリックします。 RStudioの右上に今開いているプロジェクト名が出ているので,そこから切り替えることもできます。 いまどこで作業しているか確かめたいときは getwd() を実行します。

0-2. 終了するときに聞かれる「保存」は2種類ある

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 コンソールに打った履歴 保存しなくてよい

なぜ保存しなくてよいのか。 コードが残っていれば,変数は実行し直せば作り直せます。 むしろ保存すると困ることが起きます。

前回の古い変数が残ったまま次回が始まるので, コードを直したのに結果が変わらない,逆に コードを消したのに動いてしまう(消したはずの変数がまだメモリにいる)ということが起きます。 そうなると,そのコードを他の人に渡しても動きません。

「まっさらな状態から上から順に実行すれば,同じ結果になる」という状態を保つこと。 これが分析の再現性で,この授業でずっと大事にしてほしい考え方です。

毎回聞かれないようにする設定(おすすめ)

  1. Tools → Global Options... → General
  2. Save workspace to .RData on exit: を Never にする
  3. Restore .RData into workspace at startup のチェックを外す

これで聞かれなくなり,起動のたびにまっさらな状態から始まります。

例外:計算に何十分もかかった結果だけは,残したいことがあります。 そのときはワークスペース全体ではなく,必要なものだけを明示的に保存します。

saveRDS(kekka, "kekka.rds")   # 保存
kekka <- readRDS("kekka.rds") # 読み込み



1. ggplot2とは

ggplot2 は,Rで最も広く使われているグラフ作成パッケージです。

ggplot2の特徴

  • 文法に基づいたグラフ作成(Grammar of Graphics)
  • レイヤーを重ねてグラフを組み立てる
  • 美しいデフォルトデザイン
  • 高度なカスタマイズが可能
# tidyverse を読み込む(ggplot2が含まれる)
library(tidyverse)

2. ggplot2の基本構造

レイヤー構造

ggplot2では,グラフをレイヤー(層)を重ねるように作ります。

ggplot(data = データ, aes(x = x軸の変数, y = y軸の変数)) +
  geom_xxx()   # グラフの種類を指定
要素 説明
ggplot() キャンバスを準備する
aes() 変数とグラフ要素のマッピングを指定
geom_xxx() グラフの種類(散布図・棒グラフなど)

上の「データ」「x軸の変数」「geom_xxx()」は,構造を示すための仮の書き方です。 そのまま打っても動きません。実際の名前に置き換えて使います。

複数行にまたがるコードの実行

今日から,+ で次の行へ続くコードが中心になります。

ggplot(data = iris, aes(x = Sepal.Length)) +
  geom_histogram()

これは2行で1つのグラフです。geom_histogram() の行だけを実行しても図は出ません。

グラフのコード全体をドラッグで選択してから,Ctrl + Enter(Macは Cmd + Enter)で実行してください。 選択した範囲がそのままコンソールに送られます。


3. 練習用データの準備

今日は R に最初から入っているデータセット iris を使います。

# データの確認
head(iris)      # 最初の6行を表示
# データの概要
str(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 ...
# 基本統計量
summary(iris)
##   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つだけです。 「何行・何列か」と,「数値の列と,種を表すカテゴリの列があること」です。 記号をすべて覚える必要はありません。


4. 散布図(Scatter Plot)

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length)) +
  geom_point()

色で種類を区別する

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point()

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 = "花びらの長さ") … 文字列なので引用符あり

5. ヒストグラム(Histogram)

ggplot(data = iris, aes(x = Sepal.Length)) +
  geom_histogram()

「縦軸はどこで決めたのか」

散布図では 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 刻みの区間に分けるという指定です。

  • 幅を狭くする(例:0.1)→ 細かい凹凸が見える。ただしガタガタになりやすい
  • 幅を広くする(例:0.5)→ 大まかな形が見える。ただし特徴が消えることがある

1つの幅だけ見て判断しないでください。 幅を変えると印象が変わります。 いくつかの幅を試して,山の数や偏りがどれくらい変わるかを見比べてください。 幅の取り方で山が1つに見えたり2つに見えたりします。 自分の言いたい結論に都合のよい幅だけを選ばないこと, そして論文やレポートではどの幅を使ったかを書くことが大事です。

なお fill = "steelblue" と color = "white" は aes() の外にあるので,全部の棒を同じ色にする固定指定です。


6. 棒グラフ(Bar Plot)

種ごとのデータ件数を棒グラフで表示します。

ggplot(data = iris, aes(x = Species)) +
  geom_bar()

ここでも y を指定していません。geom_bar() は,カテゴリごとの観測数を自動で数えます。

3本の棒がすべて同じ高さ(50)になりました。これは iris に各種50本ずつ入っているからです。 「3種が同じ大きさ」とか「自然界に同じ割合でいる」という意味ではありません。

すでに計算してある数値を棒の高さにしたいとき(例:種ごとの平均値)は, geom_bar() ではなく geom_col() を使います。 「数えるのが geom_bar(),与えられた値を描くのが geom_col()」と覚えてください。

色を付ける

ggplot(data = iris, aes(x = Species, fill = Species)) +
  geom_bar()


7. 箱ひげ図(Box Plot)

グループ間の分布を比較するのに便利です。

ggplot(data = iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot()

箱ひげ図の読み方

この図は,次の部品でできています。

部品 表しているもの
箱の下端 第1四分位数(下から25%の位置)
箱の中の線 中央値(真ん中の値)
箱の上端 第3四分位数(下から75%の位置)
ひげ 箱から離れすぎていない範囲の,最小値・最大値
ひげの外の点 ひげの範囲から外れた観測

つまり箱の中に,データの真ん中半分(50%)が入っています。

箱が縦に長い=真ん中50%のばらつきが大きい。短い=そろっている。 箱の高さが表しているのは \(IQR\),つまり中央50%の広がりです。 分布全体のばらつきは,箱の高さだけでは分かりません(ひげと外側の点も見ること)。 また箱の高さは「件数」ではありません。どの種も50本ずつあります。

ひげについて,もう少し正確に書いておきます。

ひげは必ずしも最小値・最大値まで伸びるわけではありません。 箱の高さ(第3四分位数 − 第1四分位数)を \(IQR\) として, \[[\,Q_1 - 1.5 \times IQR,\ \ Q_3 + 1.5 \times IQR\,]\] という範囲を考えます。ひげは,この範囲に入っている観測のうちの最小値・最大値まで伸びます。 それより外側の観測は,点として個別に描かれます。

外側の点を見つけても,「入力ミスだ」「消すべきだ」と決めつけないでください。 本当に珍しい個体かもしれませんし,重要な発見かもしれません。 まずは「そういう観測がある」と認識するところまでです。


8. タイトルと軸ラベルの追加

ggplot(data = iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point() +
  labs(
    title = "がく片の長さと花びらの長さの関係",
    x = "がく片の長さ (cm)",
    y = "花びらの長さ (cm)",
    color = "種"
  )


9. aes() のよく使うマッピング

引数 役割 例
x x軸の変数 x = Sepal.Length
y y軸の変数 y = Petal.Length
color 色(線・点) color = Species
fill 塗りつぶし色 fill = Species
size 点の大きさ size = Petal.Width
shape 点の形 shape = Species

演習

演習1:散布図

iris データを使って,Petal.Length(x軸)と Petal.Width(y軸)の 散布図を作成し,Species で色分けしてください。

ggplot(data = iris, aes(x = ___, y = ___, color = ___)) +
  geom_point()

図ができたら,次の2つに答えてください。回答は # を付けてコメントで書きます。

# 問1:この図の点1つは,何を表していますか
#

# 問2:3つの種のうち,他の2つとはっきり分かれている種はどれですか
#

点が150個より少なく見えても,データが消えたわけではありません。 同じ位置に複数の花が重なっているだけです(150本の花に対し,長さと幅の組合せは102通りしかありません)。

演習2:ヒストグラム

Petal.Width のヒストグラムを作成し,適切なタイトルと軸ラベルを付けてください。

binwidth は 0.2,色は好きなものを選んで構いません。 色の正解は1つではありません。

ggplot(data = iris, aes(x = ___)) +
  geom_histogram(binwidth = ___, fill = "___", color = "white") +
  labs(title = "___", x = "___", y = "___")

確認してほしいのは次の3点です。

  1. Petal.Width を使っているか
  2. ヒストグラムになっているか
  3. タイトルと軸ラベルが,中身と単位に合っているか(縦軸は「度数」や「花の数」)

余裕があれば:binwidth を 0.1,0.2,0.4 に変えて,見え方がどう変わるか1文で書いてみてください。

演習3:箱ひげ図

種(Species)ごとに Petal.Length の分布を箱ひげ図で比較してください。 fill = Species を追加してカラフルにしてみましょう。

ggplot(data = iris, aes(x = ___, y = ___, fill = ___)) +
  geom_boxplot() +
  labs(title = "___")

図ができたら,次に答えてください。

# 問:花びらの長さの中央値がいちばん大きい種はどれですか。
#     図のどこを見てそう判断したかも書いてください。
#

setosa の箱は,他の2種より縦に短くなります。 これは件数が少ないからではありません(どの種も50本です)。 第1四分位数から第3四分位数までの幅が狭い,つまり真ん中50%のばらつきが小さいということです。


模範解答

演習1〜3の解答例を置いてあります。自分で解いたあとに見てください。

→ 第3回 演習の模範解答(.R ファイル)

ブラウザで中身が表示されます。保存するときは右クリック →「リンク先を別名で保存」。 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つの図が表示できること
    • RStudio では,全選択(Ctrl + A)してから Ctrl + Enter(Mac は Cmd + A → Cmd + Enter) でまとめて実行できます。1行ずつ実行する必要はありません
    • source("ファイル名.R") でまとめて実行すると図が表示されません。 まとめて実行したい人は p1 <- ggplot(...) + ... と変数に入れ,print(p1) を書いてください
    • 詰まったときは模範解答を見て構いません
  • 次回は グラフのカスタマイズと保存(画像ファイルとして書き出す方法)を学びます
  • 教科書の可視化に関する章を読んでおくと理解が深まります

← 授業トップへ戻る