今回の目標

今回利用するパッケージを読み込む。ggplot2tidyverse に含まれているので、library()tidyverse を読み込めばよい。パッケージをインストール済みでない場合は、読み込みの前にまずinstall.packages() でインストールする。

#install.packages("tidyverse", dependencies = TRUE)
library(tidyverse)

データフレーム

ggplot2 で図を作るためには、データフレーム (data frame) と呼ばれる形式のデータが必要である。 そこで、まずデータフレームについて説明する。

CSVデータの読み込み

CSV形式で保存されたデータセットをもっているなら、readr::read_csv()read.csv() などでそのデータを読み込めば、データフレームができる。

例として、これまでの授業でも使った fake-data-01.csv を読み込んでみよう。プロジェクト内の data ディレクトリ(フォルダ)に fake-data-01.csv があることを想定している。

myd <- read_csv("data/fake-data-01.csv")
## 
## ── Column specification ────────────────────────────────────────────────────────
## cols(
##   id = col_double(),
##   gender = col_character(),
##   age = col_double(),
##   height = col_double(),
##   weight = col_double(),
##   income = col_double()
## )

これがデータフレームかどうか確かめるために、is.data.frame() を使う。

is.data.frame(myd)
## [1] TRUE

TRUE (真)という答えが返され、myd がデータフレームであることがわかる。

データフレームの中身は、tibble::glimpse() で確認できる。

glimpse(myd)
## Rows: 100
## Columns: 6
## $ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
## $ gender <chr> "male", "male", "male", "male", "male", "male", "male", "male",…
## $ age    <dbl> 52, 33, 22, 33, 26, 37, 50, 30, 62, 51, 55, 36, 66, 42, 36, 47,…
## $ height <dbl> 174.0, 175.3, 175.0, 170.1, 167.4, 159.3, 173.3, 162.5, 160.2, …
## $ weight <dbl> 63.1, 70.2, 82.6, 81.8, 51.2, 57.8, 68.6, 47.2, 68.2, 59.4, 66.…
## $ income <dbl> 3475810, 457018, 1627793, 6070642, 1083052, 2984929, 1481061, 1…

id, gender, age, height, weight, income という6つの変数があり、gender すなわち文字列 (character) 型で、他の変数はすべて すなわち実数 (double [double-precision floating-point]) 型であることがわかる。

データフレームの中身を確認する方法は他にもいくつかある。 View() を使うと、表計算ソフトのスプレッドシートと同じように、データを表形式で表示してくれる。 Souce ペインに表示されるので確認が終わったらタブを閉じるようにしよう。 この関数は R Markdown ファイルではなく、Console に直接入力したほうが良い。

View(myd)

ひとつひとつの変数が列(縦方向の並び)を構成し、観測個体がが行(横方向の並び)を構成していることがわかる。 View() の代わりに、RStudio の右下のペインにある Environment たぶで、Data という項目に表示されているデータの右端にあるボタンを押して、データを表示することもできる。

データフレームの各列の名前(つまり、変数名)を知りたいときは、names() を使う。

names(myd)
## [1] "id"     "gender" "age"    "height" "weight" "income"

これで、どのような名前で変数が記録されているかがわかる。

この例では変数が6つしかないので自分で変数の数を数えるのも容易である。しかし、変数の数が多い場合には、自分で数えるのは面倒だ。そのようなときは、ncol() を使う(ncol は the number of columns [列の数] の略である)。

ncol(myd)
## [1] 6

これで、myd には変数が6つあることがわかる。

また、データに含まれる観測個体の数は、nrow() で確かめることができる (the number of rows [行の数] の略である)。

nrow(myd)
## [1] 100

myd は100行あることがわかる。

dim() を使えば、行数と列数を1度に調べることができる。

dim(myd)
## [1] 100   6

実は、行数と列数は、上でglimpse(myd) を実行したときにも表示されていた。

データの先頭の数行を表示して変数の中身を確認したいときは、head() を使う。

head(myd)
## # A tibble: 6 x 6
##      id gender   age height weight  income
##   <dbl> <chr>  <dbl>  <dbl>  <dbl>   <dbl>
## 1     1 male      52   174    63.1 3475810
## 2     2 male      33   175.   70.2  457018
## 3     3 male      22   175    82.6 1627793
## 4     4 male      33   170.   81.8 6070642
## 5     5 male      26   167.   51.2 1083052
## 6     6 male      37   159.   57.8 2984929

このように、デフォルトでは最初の6行が表示される。表示する行数は、自分で指定できる。引数 nを使う。

head(myd, n = 4)
## # A tibble: 4 x 6
##      id gender   age height weight  income
##   <dbl> <chr>  <dbl>  <dbl>  <dbl>   <dbl>
## 1     1 male      52   174    63.1 3475810
## 2     2 male      33   175.   70.2  457018
## 3     3 male      22   175    82.6 1627793
## 4     4 male      33   170.   81.8 6070642

同様に、データの末尾は tail() で表示できる。

tail(myd, n = 5)
## # A tibble: 5 x 6
##      id gender   age height weight   income
##   <dbl> <chr>  <dbl>  <dbl>  <dbl>    <dbl>
## 1    96 female    65   161.   46.8  6127136
## 2    97 female    45   161.   48.7  1062663
## 3    98 female    53   166.   64.2 10154200
## 4    99 female    43   158.   48.5  8287163
## 5   100 female    48   154.   42    1125390

データの中身をさらに詳しく知りたい場合には、str() (structure) を使う。

str(myd)
## spec_tbl_df[,6] [100 × 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id    : num [1:100] 1 2 3 4 5 6 7 8 9 10 ...
##  $ gender: chr [1:100] "male" "male" "male" "male" ...
##  $ age   : num [1:100] 52 33 22 33 26 37 50 30 62 51 ...
##  $ height: num [1:100] 174 175 175 170 167 ...
##  $ weight: num [1:100] 63.1 70.2 82.6 81.8 51.2 57.8 68.6 47.2 68.2 59.4 ...
##  $ income: num [1:100] 3475810 457018 1627793 6070642 1083052 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   gender = col_character(),
##   ..   age = col_double(),
##   ..   height = col_double(),
##   ..   weight = col_double(),
##   ..   income = col_double()
##   .. )

この情報はR初心者にはわかりにくいと思われるので、最初は glimpse() を使った方がいいだろう。

データセットをRに読み込んだら、glimpse() をはじめとするさまざまな関数を使って、データの中身を確認する習慣を身につけよう。

データフレームの作成

データフレームは、data.frame() を使ってRで作ることもできる。データフレームの代わりにtibble と呼ばれる形式のデータを使うこともできる。tibble は、tibble::tibble() で作れる。

練習のために、df1という名前のデータフレームと、df2という名前のtibble を作ってみよう。まず、x とy という2つの変数をもつ df1 を作る。

df1 <- data.frame(x = 1:100, 
                  y = 100:1)
is.data.frame(df1)
## [1] TRUE

このデータの中身を確認してみよう。

glimpse(df1)
## Rows: 100
## Columns: 2
## $ x <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2…
## $ y <int> 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84,…

xy という変数があり、それぞれが すなわち整数 (integer) 型であることがわかる。また、データは100行2列である。

次に、v1, v2, v3 という3つの変数をもつ df2 を作る。rnorm(n, mean, sd) で、平均がmean、標準偏差がsd の正規分布から n 個の乱数を生成することができる(詳しくは、「シミュレーション」の回に説明する)。

df2 <- tibble(v1 = rnorm(100, mean =  0, sd = 5),
              v2 = rnorm(100, mean = -4, sd = 5),
              v3 = rnorm(100, mean =  0, sd = 1))
is.data.frame(df2)
## [1] TRUE

df2 の中身を確認しておこう。

glimpse(df2)
## Rows: 100
## Columns: 3
## $ v1 <dbl> -3.4588462, 3.6477649, -1.1223656, -3.8149316, 7.3289872, -2.920685…
## $ v2 <dbl> 4.5036501, -0.8644444, -12.8516999, -4.9967586, 1.5024545, -5.40636…
## $ v3 <dbl> -0.501376988, 0.489839417, -1.052405132, -0.930425648, -0.396721603…

v1, v2, v3 という3つの変数があり、それぞれが すなわち実数型であることがわかる。このデータフレームは100行3列である。

このように、data.frame()tibble() を使って、df1とdf2のという “data.frame” (データフレーム)を作ることができた。基本的にはどちらの方法でデータフレームを作っても良いが、 特にdata.frame() のほうを好む理由がなければ、今後は tibble() でデータフレーム (tibble) を作ろう。 (tibble を優先する理由の説明は割愛するが、Consoleに直接 df1 [これは data.frame である] と入力して実行した結果と、 同じく df2[これは tibble である] と入力して実行した結果を比べると、tibble のほうが良い理由の1つがわかるだろう。)

組み込みデータ

Rにはあらかじめいくつかの(多くの!)データフレームが用意されている。たとえば、自動車に関するデータセットであるmtcarsというものがある。このデータは、data() で呼び出すことができる。

data(mtcars)

これを実行すると、RStudio 右下ペインの Environement タブの中で、Values という項目のところに、mtcars が表示されるはずだ。この中身を確認してみよう。

glimpse(mtcars)
## Rows: 32
## Columns: 11
## $ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8,…
## $ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8,…
## $ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 16…
## $ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180…
## $ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92,…
## $ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.…
## $ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18…
## $ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,…
## $ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,…
## $ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3,…
## $ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2,…

32行11列のデータであることがわかる。この時点で、 Environement タブの中で Data 項目の中に mtcars が移動し、データフレームとして認識されていることがわかる。念のために確認しておこう。

is.data.frame(mtcars)
## [1] TRUE

このデータの詳細を確認したければ、次のコマンドで。

?mtcars

他にどんなデータが利用可能か確認したければ、以下を実行する。

data()

ggplot2の基礎

ggplot2 とは何か

ggplot2 は、Rで綺麗な図を作るためのパッケージである。 RStudio のChief Scientist である Hadley Wickham が大学院生時代に開発・公開し、アップデートを重ねてきたものである(Hadley は tidyverse などの重要パッケージ開発の中心人物であり、世界中のRユーザから最も尊敬されている人物だと考えられる。日本の一部のRユーザは彼を「羽鳥先生」と呼ぶ)。

ggplot2 の gg は grammar of graphics(図のための文法) という意味で、一貫した方法で様々な図が作れるように工夫されている。 最初は文法を覚えるのに少し苦労するかもしれない。しかし、一度文法を身につけてしまえば、様々な図を簡単に作れるようになるので、とても便利である。また、デフォルト(既定)の設定でそれなりに綺麗な図が作れるのも魅力である(某表計算ソフトのように、何も考えずに 3D棒グラフのような醜い図を作ってしまうということが防げる)。

ggplot2 についての詳しい説明は、Hadley自身が書いた ggplot2: Elegant Graphics for Data Analysis, 2nd ed. (Springer) で読める(PDFファイル が無料で公開されている)。

また、チートシート(日本語版; 英語版)が公開されているので、ダウンロードしていつでも見られるようにしておくと、便利である。

ggplot2 パッケージの読み込み

このページの冒頭に書いたとおり、。ggplot2tidyverse に含まれているので、library()tidyverse を読み込めばよい。上で実行したなら、再度実行する必要はない。パッケージをインストール済みでない場合は、読み込みの前にまずinstall.packages() でインストールする。

#install.packages("tidyverse", dependencies = TRUE)
library(tidyverse)

次に日本語が正しく表示されるようにするため、theme_set() で使用する文字フォントを指定する。OSによって命令がやや異なるので注意されたい。 以下のチャンクは、どのOSでも動くように適切に場合分けを行う(ただし、Windows の場合には fontregisterer というパッケージをあらかじめインストールしておく必要がある。これについては前回の実習資料を参照)。 また、以下はあくまで例であり、他のフォントを使用しても良い(各自のパソコンにインストールされているフォントは私にはわからないので、変えたいなら自分で調べる。もちろん、日本語が表示できるフォントが必要)。また、RStudio Cloud を利用している場合は、日本語を表示することができない(一応表示する方法もあるが、ものすごく面倒なので割愛する)ので、諦めて英語を使おう(この授業では、レポートの本文が日本語で図のラベルが英語でも許容する。しかし、本来は日本語のレポートなら図のラベルもすべて日本語にすべきである。あるいは、英語で図を作るなら、本文も英語にすべきである)。

ggplot の基本的な使い方

ggplot2::ggplot() を使って図を作る手順は次のとおりである。

  1. 作図対象となるデータを ggplot() に入力する
    • data: データを指定
    • mapping: どの変数を図のどこで利用するか指定
  2. geom_xxx() で図の層を加える(xxx の部分はグラフの種類によって変わる)
  3. ラベル (label) や凡例 (legend) の指定、作図範囲の絞り込み、軸の交換などを行う
  4. plot() で図を表示する

順番にやってみよう。


例1:散布図

上で読み込んだ mtcars は自動車に関するデータである。例として、燃費 (mile per gallon; mpg) と車の重量 (weight; wt) の関係を散布図にしてみよう。

まず、 作図対象となるデータを指定する。また、作図の対象となる変数を指定する。ここでは、散布図の横軸 xに wt、縦軸yに mpg を指定する。

p1_1 <- ggplot(data = mtcars, 
               mapping = aes(x = wt, y = mpg)) 

同じことだが、datamapping は書略して

p1_1 <- ggplot(mtcars, aes(x = wt, y = mpg)) 

と書くことが多い。

この時点で図を表示してみる。

plot(p1_1)

指定した通り、横軸にwt、縦軸にmpgをとった図を描く準備ができているが、グラフ自体はまだない。

ここに、散布図を作るための層 (layer) を加える。図を作るためには、geom_xxx() のように、geom から始まる関数で新たな層 (layer) を加える必要がある。geom とは geometry(形状)のことである。たとえば、ヒストグラム (histogram) を作るときはgeom_histogram() を、箱ひげ図 (box[-and-whisker] plot) を作るときは geom_boxplot() を使う。

散布図は、geom_point() でできる。

p1_2 <- p1_1 + geom_point()

このように、前に作ったものに + で何かを加えることで、ggplot に新たな要素を追加することができる。この時点で、作った図を表示してみよう。

plot(p1_2)

散布図ができた。

次に、ラベルをわかりやすいものに変える。labs() で変更する。(注意: RStudio Cloud を使っている場合は日本語不可。日本語を正しく表示するために事前準備が必要。上の説明を参照。)

p1_3 <- p1_2 + 
    labs(x = "重量 (1000 lbs)", 
         y = "燃費 (Miles / US gallon)")

表示してみる。

plot(p1_3)

これで散布図ができた。

慣れてきたら、一度にコマンドを書いてもよい。

p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) +
    geom_point() +
    labs(x = "重量 (1000 lbs)", 
         y = "燃費 (Miles / US gallon)")
plot(p1)


例2:ヒストグラム

引き続き mtcars を使う。燃費 (mile per gallon; mpg) のヒストグラムを作ってみよう。

まず、作図対象となるデータを入力する。また、作図対象となる変数を指定する。ヒストグラムは1つの変数を可視化するグラフなので、aes にはxのみ指定する。

p2_1 <- ggplot(mtcars, aes(x = mpg)) 

この時点で図を表示してみる。

plot(p2_1)