4  Rによるデータ操作

今回の目標

4.1 準備

準備として、必要なパッケージを読み込み、図の日本語が正しく表示されるようにする。

pacman::p_load(tidyverse,
               haven,
               readxl)

(大学のPCで)pacman::p_load() がうまくいかない場合は、以下のようにパッケージを1つずつ読み込む(次回以降も同じようにする)。

次に、ggplot2のテーマとフォントの設定を行う。自分好みの設定がある場合は自由に変えてよい。LinuxにはIPAexフォント がインストールされていることを想定している(IPAex はインストールすれば maxOSやWindows でも使える)。

if (.Platform$OS.type == "windows") { 
  if (require(fontregisterer)) {
    my_font <- "Yu Gothic"
  } else {
    my_font <- "Japan1"
  }
} else if (capabilities("aqua")) {
  my_font <- "HiraginoSans-W3"
} else {
  my_font <- "IPAexGothic"
}

theme_set(theme_gray(base_size = 9,
                     base_family = my_font))

4.2 データの読み込み

4.2.1 CSV 形式のデータを読む

データの形式として最もよく使われるものの1つが、CSV (comma separated values) という形式である。これはただのテキストファイルであり、値がカンマで区切られているだけである。

この形式のファイルの中身を理解するために、 fake_data_02.csv を利用しよう。 まずは、上のダウンロードして、プロジェクト内の data ディレクトリ(フォルダ)にファイルを保存する。

download.file(
    url = "https://yukiyanai.github.io/jp/classes/econometrics1/contents/data/fake_data_02.csv",
    destfile = "data/fake_data_02.csv"
)

ダウンロードがうまくできないとき(この後開いてみたら中身が壊れているとき)は、ブラウザ上でデータのリンクをクリック(あるいは右クリック; 副クリック)してファイルを保存し、プロジェクト内の data フォルダにダウンロードしたファイルをを移動しよう(以下で登場するファイルについても同様)

ファイルがダウンロードできたら、そのファイルを開いてみよう。

まず、エクスプローラー(Macの場合はファインダ)でこのファイルを右クリック(副クリックまたは control を押しながらクリック)し、「プログラムから開く」を選び、LibreOffice Calc または Microsoft Excel で開いてみよう。見慣れた形式(スプレッドシート)でデータが見えるはずだ。確認できたらCalc/Excelを閉じよう。

次に、同じファイルを同様に「プログラムから開く」でVisual Studio Code(またはその他のテキストエディタ)で開いてみよう。ファイルの中身が見えるはずだ。CSV ファイルは、1行目は変数の名前、2行目以降は各行が1つの観測(このデータの場合は1人)、各行で異なる変数の間にカンマがある(そのため、カンマ区切りデータと呼ばれる)という特徴がある。

この形式のメリットとして、

  • テキストファイルなのでファイルの中身が単純明快
  • 容量が小さい
  • どんな統計ソフトでも読める
  • 統計ソフトがなくてもメモ帳さえあれば編集可能

などがあげられる(注意:このファイルを Word 等のワープロソフトで編集しないように。余分な内容が追加されてデータの中身が変わってしまう。)。

Excel 等に自分でデータを打ち込んで新しいデータセットを作るときは、できるだけこのCSV 形式を選んだ方がよい。

CSV形式のデータは、readr::read_csv() でRに読み込むことができる。

mycsv1 <- read_csv('data/fake_data_02.csv')
Rows: 100 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): sex
dbl (5): id, age, height, weight, income

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

プロジェクト内の data という名前のフォルダに入っていることを data/ の部分で示し、そのフォルダ内の fake_data_02.csv を指定して開いている。 このとき、引用符を忘れないように注意する。引用符はシングル「’」でも、ダブル 「“」でもよい。

RStudio でデータを読み込むと、右下の EnvironmentタブのDataのところに読み込んだデータセットが表示される。

念のために中身を少しだけ確認しておこう。

glimpse(mycsv1)
Rows: 100
Columns: 6
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
$ sex    <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…

4.2.2 Excel 形式のデータを読む

Excel のデータは、.xlsx または .xls というファイル名拡張子付きで保存されている。 このデータをRで読む方法もあるが、ここではExcel 形式のデータをCSV形式に変換し、それを上で説明した方法で読むことにする。

例として、fake_data_03.xlsx を使う。まず、このデータをダウンロードし、Excel で開こう。

download.file(
    url = "https://yukiyanai.github.io/jp/classes/econometrics1/contents/data/fake_data_03.xlsx",
    destfile = "data/fake_data_03.xlsx"
)

これを、CSV形式に変換し、プロジェクト内の data フォルダに保存する。そのために、以下を実行する。

  1. Calc/Excel 左上の「ファイル」から「名前を付けて保存」を選ぶ
  2. 保存先として、プロジェクト(例:ドキュメント/econometrics)内の data フォルダを選ぶ
  3. ポップアップで出てきたウィンドウの「ファイルの種類」で、CSV(カンマ区切り)(*.csv) を選び、保存する

保存できたら、RStudioの右下の data フォルダをクリックし、fake_data_03.csv が保存されていることを確かめよう。

あとは先ほどと同様の方法でデータを読めばいいので、

mycsv2 <- read_csv("data/fake_data_03.csv")
Rows: 100 Columns: 6
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (1): sex
dbl (5): id, age, height, weight, income

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

と、する。RStudio の Environment タブで、データが読み込めたこと(mycsv2というデータが追加されたこと)を確認しよう。

念のために中身を少しだけ確認しておこう。

glimpse(mycsv2)
Rows: 100
Columns: 6
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
$ sex    <chr> "male", "male", "male", "male", "male", "male", "male", "male",…
$ age    <dbl> 46, 22, 61, 48, 44, 23, 46, 60, 30, 25, 26, 22, 36, 65, 20, 58,…
$ height <dbl> 168.3, 177.1, 171.6, 170.2, 168.5, 160.7, 170.3, 163.7, 174.8, …
$ weight <dbl> 72.1, 85.4, 81.8, 65.2, 66.0, 50.8, 75.1, 67.1, 76.7, 63.7, 72.…
$ income <dbl> 2102061, 2729262, 1193016, 3014919, 3982087, 3702544, 7930623, …

あるいは、readxl::read_excel() でExcelファイルを読み込むこともできる。

#pacman::p_load(readxl)
myxl <- read_excel("data/fake_data_03.xlsx")

念のために中身を少しだけ確認しておこう。

glimpse(myxl)
Rows: 100
Columns: 6
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
$ sex    <chr> "male", "male", "male", "male", "male", "male", "male", "male",…
$ age    <dbl> 46, 22, 61, 48, 44, 23, 46, 60, 30, 25, 26, 22, 36, 65, 20, 58,…
$ height <dbl> 168.3, 177.1, 171.6, 170.2, 168.5, 160.7, 170.3, 163.7, 174.8, …
$ weight <dbl> 72.1, 85.4, 81.8, 65.2, 66.0, 50.8, 75.1, 67.1, 76.7, 63.7, 72.…
$ income <dbl> 2102061, 2729262, 1193016, 3014919, 3982087, 3702544, 7930623, …

4.2.3 複数のデータセットの扱い

ここまでで3つのデータセットを読み込んだ(そのうち2つの内容は同じだが)ので、RStudioのEvironment タブには、3つのデータセット(データフレーム)、mycsv1, mycsv2, myxl が表示されているはずである。このように、Rには複数のデータを同時に利用できるというメリットがある。

このうち、csvファイルから読み込んだデータセットについて、データに含まれる変数を確認してみよう。

names(mycsv1)
[1] "id"     "sex"    "age"    "height" "weight" "income"
names(mycsv2)
[1] "id"     "sex"    "age"    "height" "weight" "income"

2つのデータセットに含まれる変数名は同じようである。

では、2つのデータはまったく同じものだろうか。ためしに、それぞれのデータセット身長 (height) の平均値を求めてみよう。

mean(mycsv1$height)
[1] 163.746
mean(mycsv2$height)
[1] 162.907

平均値が異なる。つまり、変数名は同じでも、データの中身は違うようだ。

このように、異なるデータセットが同じ名前の変数を含んでいることがあるので注意が必要だ。既に学習したとおり、Rでは データセット名$変数名 とすることで、同じ名前の変数でも、異なるデータセットに属している場合にはそれらを区別して利用することができる。

4.2.4 他の統計ソフト用のデータを読む

4.2.4.1 Stata

R以外に計量経済学でよく利用される分析ソフトとして、Stataというものがある。Stata のデータセットには、.dta というファイル名拡張子が付いている。

StataのファイルをRで読みたいときは、haven というパッケージに含まれる read_dta()という関数を使う。

例として、fake_data_stata.dta をダウンロードし、data フォルダに保存しよう。

download.file(
    url = "https://yukiyanai.github.io/jp/classes/econometrics1/contents/data/fake_data_stata.dta",
    destfile = "data/fake_data_stata.dta"
)

これを読むには、まず haven パッケージを読み込むことが必要である(インストールされていない場合はまずインストールする)。

#pacman::p_load(haven)

パッケージが読み込めたら、データを読む。

mydta <- read_dta("data/fake_data_stata.dta")

RStudio の Environment タブで、データが読み込めたことを確認しよう。

念のために中身も少しだけ確認しておこう。

glimpse(mydta)
Rows: 100
Columns: 6
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
$ sex    <chr> "male", "male", "male", "male", "male", "male", "male", "male",…
$ age    <dbl> 31, 57, 52, 46, 58, 49, 52, 34, 57, 41, 43, 43, 40, 45, 41, 64,…
$ height <dbl> 166.6, 154.3, 168.1, 178.9, 168.7, 155.1, 169.1, 174.4, 166.8, …
$ weight <dbl> 59.8, 51.4, 61.2, 71.8, 70.5, 32.7, 62.2, 70.2, 68.5, 55.3, 56.…
$ income <dbl> 1094707, 370882, 12449508, 25811696, 1182427, 706000, 825437, 1…

4.2.4.2 SPSS

かつてよく使われた(今でも経済学以外の分野では使われることがある)統計分析ソフトに、SPSSというものがある。 SPSS 形式のデータには、.savという拡張子が付いている。 Rでは、haven::read_sav() (または haven::read_spss())で読み込める。

例として、fake_data_spss.sav をダウンロードし、data フォルダに保存しよう。

download.file(url = "https://yukiyanai.github.io/jp/classes/econometrics1/contents/data/fake_data_spss.sav",
              destfile = "data/fake_data_spss.sav")

このファイルは、以下のコマンドで読み込める。

mysav <- read_sav("data/fake_data_spss.sav")

RStudio の Environment タブで、データが読み込めたことを確認しよう。

念のために中身も少しだけ確認しておこう。

glimpse(mysav)
Rows: 100
Columns: 6
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, …
$ sex    <dbl+lbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
$ age    <dbl> 67, 57, 58, 40, 24, 59, 58, 31, 24, 53, 31, 29, 40, 61, 43, 53,…
$ height <dbl> 167.7, 167.1, 164.9, 171.7, 167.2, 172.9, 160.6, 167.7, 167.9, …
$ weight <dbl> 58.5, 54.5, 62.9, 68.8, 59.8, 83.6, 54.5, 72.9, 57.6, 54.2, 49.…
$ income <dbl> 1659808, 1550051, 3139595, 4563089, 1864069, 5311530, 42952064,…

4.2.4.3 その他

Rはこの他には様々な形式のデータを読むことができる。必要に応じて他の方法も解説するが、この授業で他の形式が必要になることはないはずである。

4.3 データの前処理

当たり前のことだが、データ分析にはデータが必要である。データはどうやって手に入れればいいだろうか。

現代では、インターネットを通じて様々なデータセットを手に入れることができる。例えば、日本の政府が集めたデータ(政府統計)の多くは、総務省統計局のウェブサイトe-Stat から入手できる。あるいは、先進諸国の経済指標は、OECD.Stat からダウンロードすることができる。

データを入手したらすぐ分析したくなるだろう。しかし、たいていの場合、入手したデータをそのままの状態で分析するのは難しい。インターネットからダウンロードしたデータセットは、データ分析に適した形式でなかったり、分析対象となる変数以外の余計な情報を含んでいたり、変数の中におかしな値(典型的には、入力ミス)をもっていたりする。そのようなデータセットをありのままで分析しようとすると、誤った推論をしたり、分析を実行するためのRコードがそもそも動かないという問題に直面する。

そこで必要になるのが、データの前処理 (pre-processing) である。データの収集から分析結果の報告までの一連の過程全体を「データ分析」と呼ぶことにすると、通常、データ分析でもっとも多くの時間を割くのが「前処理」の部分である。たとえば、線形回帰分析を実行することを考えよう。自分が推定した特定の統計モデル(統計モデルについては今後の授業で説明する)とそのために必要なデータフレームさえあれば、回帰分析は lm() ですぐに実行可能である。つまり、統計モデルを推定するのは、1つのコマンドで実行可能である。

しかし、これを可能にするためには、lm() が期待する形式でデータフレームを用意する必要がある。具体的には、行列形式のデータセットで、各行\(i\)が1ひとつの観測個体を表しており、各列\(j\)が各変数を表し、各セル (\(i, j\)) が個体\(i\)の変数\(j\)の値を保持している必要がある。これまではすでにこの形式で用意されたデータセットを使って実習してきたが、この形式のデータを作るのは、必ずしも楽ではない。少なくとも、決まったRのコマンドを1つ実行しさえすれば望んだデータフレームができるというような簡単な作業ではない。

データの前処理は、データ分析をする上で避けて通れない道である。今回は、Rでデータの前処理をするための便利な方法を学習しよう。

4.3.1 Tidy なデータ

まず、最終的にどのようなデータフレームが必要かを理解しよう。ここでは、データ分析の方法として一般的な線形回帰分析(あるいは、一般化線形モデル; GLM)を行うためのデータフレームを考える(他の方法で分析を行う場合は、異なる形式のデータフレームを用意する必要があるかもしれない。たとえば、コンジョイント分析を行う場合には、今回説明するものとは異なるデータフレームが必要である)。

私たちが通常必要とするのは、tidy data(整然データ)と呼ばれるものである。整然データについては、宋・矢内『私たちのR』第16章を参照されたい。整然データを用意すれば、回帰分析だけでなく、ggplot2 を使った作図にも使える。

Tidy data は、次の4つの条件を満たすデータである。

  1. 1つの列は、1つの変数を表す。
  2. 1つの行は、1つの観測を表す。
  3. 1つのセル(特定の列の特定の行)は、1つの値を表す。
  4. 1つの表は、1つの観測単位 (unit of observation) をもつ(異なる観測単位が混ざっていない)

データを入手したら(あるいは、自分でデータセットを作るときは)、この条件がすべて満たされているか確認しよう。満たされていなければ、tidy data に変換するための前処理が必要になる。

4.3.2 様々な前処理

CSVファイルは用意されていると仮定する。

官庁のウェブサイト等で公開されているデータは、ファイルの冒頭にデータの説明文などの、データセットの中身ではない情報が含まれている場合がある。例えば、最初の3行が余計だとすると、その3行をとばしてデータを読み込みたい。そういう場合は、readr::read_csv()skip 引数を指定する。foo.csv というデータセットがあるとすると(実際にはないので、以下のコマンドを実行してもエラーになる。以下、「あるとする」と言った場合は同様)、次のようにして読める。

MYD <- read_csv("foo.csv", skip = 3)

Rでは欠測値(本来ならセルに入っているべき値が、何らかの理由 [アンケートでの回答拒否、政府が情報を公開していない、etc.] で欠けている場合)は、NA で表すことになっている。 自分が用意したCSVファイル(あるいはその元になったMS Excel ファイル)で、 NA と入力されているか完全に空欄になっているセルがある場合、readr::read_csv() は自動的にRのNA に変換してくれる。しかし、インターネット等でダウンロードしたファイルでは、欠測を他の方法で表記している場合があり、対応が必要である。read_csv() では、na 引数を指定すればよい。例えば、欠測が.(ドット)で表されている foo.csv があるとすれば、

MYD <- read_csv("foo.csv", na = '.') 

とすればよい。あるいは、欠測が 99 または -9 のいずれかで表現されているなら、

MYD <- read_csv("foo.csv", na = c(99, -9))

とする。

ここからは、実際のデータを使って実習しよう。 『Rによる計量政治学』(浅野正彦, 矢内勇生. 2018)で使用されているデータ(hr-data.csv)を使う。

まず、データをダウンロードして保存する。

download.file(
    url = "https://raw.githubusercontent.com/yukiyanai/quant-methods-R/master/data/hr-data.csv",
    destfile = "data/hr-data.csv"
)

データを読み込む。

myd <- read_csv("data/hr-data.csv")
Rows: 8803 Columns: 22
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (7): ku, status, name, party, wl, smd, party_jpn
dbl (15): year, kun, party_code, previous, voteshare, age, nocand, rank, vot...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

download.file() でダウンロードできなかったり、ダウンロードしたファイルが壊れているときは、データのリンクをクリック(または右クリック)して手動でダウンロードして使う(今後も同様)。

既に学習済みのはずだが、特定の条件を満たす部分だけ利用したい場合は、dplyr::filter() を使う。 year の値が1996で、party_jpn が自民党のものだけ取り出してみよう。 取り出す前のデータを確認する。

with(myd, table(year, party_jpn))
      party_jpn
year   さきがけ その他 みんな 保守党 保守新党 公明党 共産党 国民党 国民新党
  1996       13     20      0      0        0      0    299     10        0
  2000        0      8      0     16        0     18    300      0        0
  2003        0      3      0      0       11     10    300      1        0
  2005        0      1      0      0        0      9    275      0       10
  2009        0      1     14      0        0      6    152      0        9
  2012        0      5     65      0        0      9    299      0        2
  2014        0      5      0      0        0      9    292      0        0
  2017        0     44      0      0        0      9    206      0        0
      party_jpn
year   大地 希望 幸福実現党 新党日本 新社会党 新進党 未来 次世代 民主党 無所属
  1996    0    0          0        0       37    235    0      0    143     85
  2000    0    0          0        0        1      0    0      0    242     79
  2003    0    0          0        0        0      0    0      0    267     92
  2005    1    0          0        6        0      0    0      0    289     70
  2009    0    0        292        2        0      0    0      0    271     70
  2012    7    0         20        1        0      0  111      0    264     48
  2014    0    0          0        0        0      0    0     39    178     45
  2017    0  198          0        0        0      0    0      0      0     73
      party_jpn
year   無所属の会 生活 社民党 立憲民主党 維新の会 維新の党 自民党 自由党
  1996          0    0     43          0        0        0    288      0
  2000          9    0     71          0        0        0    271     61
  2003          0    0     64          0        0        0    277      0
  2005          0    0     38          0        0        0    290      0
  2009          0    0     31          0        0        0    291      0
  2012          0    0     23          0      151        0    289      0
  2014          0   13     18          0        0       77    283      0
  2017          0    0     19         63       47        0    277      0
      party_jpn
year   自由連合
  1996       88
  2000      123
  2003        1
  2005        0
  2009        0
  2012        0
  2014        0
  2017        0

filter で条件(1996年の自民党候補)を満たすものを取り出す。

LDP1996 <- filter(myd, year == 1996, 
                  party_jpn == "自民党")

確認する。

with(LDP1996, table(year, party_jpn))
      party_jpn
year   自民党
  1996    288

上の操作は、パイプ |> を使うと次のように書ける。

LDP1996 <- myd |> 
    filter(year == 1996, 
           party_jpn == "自民党")

特定の変数だけを残したい場合は、dplyr::select() で変数を指定する。 まず、myd にどんな変数があるのか見てみよう。

names(myd)
 [1] "year"       "ku"         "kun"        "status"     "name"      
 [6] "party"      "party_code" "previous"   "wl"         "voteshare" 
[11] "age"        "nocand"     "rank"       "vote"       "eligible"  
[16] "turnout"    "exp"        "expm"       "vs"         "exppv"     
[21] "smd"        "party_jpn" 

この中で、yearnamevs だけ残してみよう。

sub1 <- myd |> 
    select(year, name, vs)
names(sub1)
[1] "year" "name" "vs"  

kun からparty までの変数をすべて残したいときは、次のように書ける。

sub2 <- myd |> 
    select(kun:party)
names(sub2)
[1] "kun"    "status" "name"   "party" 

特定の変数だけ除外したいときは、!を使って指定する。statusvs だけ消してみよう。

sub3 <- myd |> 
    select(!c(status, vs))
names(sub3)
 [1] "year"       "ku"         "kun"        "name"       "party"     
 [6] "party_code" "previous"   "wl"         "voteshare"  "age"       
[11] "nocand"     "rank"       "vote"       "eligible"   "turnout"   
[16] "exp"        "expm"       "exppv"      "smd"        "party_jpn" 

特定の文字から始まる変数だけ残したいときは、starts_with() が使える。変数名が “e” から始まるものだけ残してみよう(この例には特に意味はないが、変数名が x1, x2, x3, y1, y2, y3,… のようになっていて、xから始まる変数だけ取り出したいときなどに便利である)。

sub4 <- myd |> 
    select(starts_with("e"))
names(sub4)
[1] "eligible" "exp"      "expm"     "exppv"   

同じように、特定の文字で終わるものは、ends_with() で取り出せる。変数名が “d” で終わるものだけ残してみよう(この例には特に意味はないが、変数名が x2000, x2001, x2002, …, y2000, y2001, y2002,… のようになっていて、“2000”で終わる変数だけ取り出したいときなどに便利である)。

sub5 <- myd |> 
    select(ends_with("d"))
names(sub5)
[1] "nocand" "smd"   

変数名に特定の文字列を含むものは、contains() で取り出せる。変数名に”te” が含まれるものだけ取り出してみよう。

sub6 <- myd |> 
    select(contains("te"))
names(sub6)
[1] "voteshare" "vote"     

filter()してからselect() するなど、複数の操作を行いたいときは、パイプでつなぐ。例えば、

LDP1996_sub1 <- myd |> 
    filter(year == 1996, 
           party_jpn == "自民党") |> 
    select(year, name, vs)
names(LDP1996_sub1)
[1] "year" "name" "vs"  

ということができる。つまり、|> (パイプ)は、“and then” という接続詞である考えることができる。

これをパイプを使わずに実行するには、次のように書く必要がある。

LDP1996_sub1_2 <- select(filter(myd, year == 1996, party_jpn == "自民党"), year, name, vs)
names(LDP1996_sub1_2)
[1] "year" "name" "vs"  

書くのも読むのも大変である。

新しい変数を作りたいときは、dplyr::mutate() を使う。例えば、パーセント(0以上100以下)で測定されている turnout(投票率)という変数を元に、0から1の範囲で投票率を測るturnout2という変数を作りたいなら、次のようにする。

myd <- myd |> 
    mutate(turnout2 = turnout / 100)
rbind(
  summary(myd$turnout),
  summary(myd$turnout2)
)
       Min. 1st Qu. Median       Mean  3rd Qu.   Max. NA's
[1,] 48.900  57.800 62.700 62.9562247 67.52500 83.800 1895
[2,]  0.489   0.578  0.627  0.6295622  0.67525  0.838 1895

複数の変数を同時に作ることもできる。自民党候補であることを表す LDP というダミー変数と、民主党候補のDPJダミーを作ろう。

myd <- myd |> 
    mutate(LDP = ifelse(party_jpn == "自民党", 1, 0),
           DPJ = ifelse(party_jpn == "民主党", 1, 0))
with(myd, table(party_jpn, LDP))
            LDP
party_jpn       0    1
  さきがけ     13    0
  その他       87    0
  みんな       79    0
  保守党       16    0
  保守新党     11    0
  公明党       70    0
  共産党     2123    0
  国民党       11    0
  国民新党     21    0
  大地          8    0
  希望        198    0
  幸福実現党  312    0
  新党日本      9    0
  新社会党     38    0
  新進党      235    0
  未来        111    0
  次世代       39    0
  民主党     1654    0
  無所属      562    0
  無所属の会    9    0
  生活         13    0
  社民党      307    0
  立憲民主党   63    0
  維新の会    198    0
  維新の党     77    0
  自民党        0 2266
  自由党       61    0
  自由連合    212    0
with(myd, table(party_jpn, DPJ))
            DPJ
party_jpn       0    1
  さきがけ     13    0
  その他       87    0
  みんな       79    0
  保守党       16    0
  保守新党     11    0
  公明党       70    0
  共産党     2123    0
  国民党       11    0
  国民新党     21    0
  大地          8    0
  希望        198    0
  幸福実現党  312    0
  新党日本      9    0
  新社会党     38    0
  新進党      235    0
  未来        111    0
  次世代       39    0
  民主党        0 1654
  無所属      562    0
  無所属の会    9    0
  生活         13    0
  社民党      307    0
  立憲民主党   63    0
  維新の会    198    0
  維新の党     77    0
  自民党     2266    0
  自由党       61    0
  自由連合    212    0

変数名を変えるには、dplyr::rename() を使う。

例えば、turnout2 の名前を tohyoritsu に変更するには、次のようにする。

myd <- myd |>  
    rename(tohyoritsu = turnout2)
names(myd)
 [1] "year"       "ku"         "kun"        "status"     "name"      
 [6] "party"      "party_code" "previous"   "wl"         "voteshare" 
[11] "age"        "nocand"     "rank"       "vote"       "eligible"  
[16] "turnout"    "exp"        "expm"       "vs"         "exppv"     
[21] "smd"        "party_jpn"  "tohyoritsu" "LDP"        "DPJ"       

教科書 5.3.3節 (p.78から) の例を考える。 まず、横長データ を手に入れる(download.file() がうまくいかないときは、リンクをクリックして保存)。

download.file(url = "https://git.io/fAnmx",
              destfile = "data/wide-table.csv")

データファイルを読んで中身を確認する。

GDP <- read_csv("data/wide-table.csv")
GDP
# A tibble: 3 × 4
  country gdp2000 gdp2005 gdp2010
  <chr>     <dbl>   <dbl>   <dbl>
1 A         40000   42000   44000
2 B         38000   40000   43000
3 C         52000   52100   52500

これを縦長に変更する。(教科書第1刷では、tidyr::gather() の使い方が紹介されているが、)ここではtidyr::pivot_longer() を使おう。

GDP_long <- GDP |> 
    pivot_longer(cols = !country,      # 縦長にする範囲:country 以外
                 names_to = "year",    # 元の列がどれだっかを区別する変数:年
                 names_prefix = "gdp", # 元の変数名のうち、区別に不要な部分
                 values_to = "gdp")    # 元の値を保持する変数名
GDP_long
# A tibble: 9 × 3
  country year    gdp
  <chr>   <chr> <dbl>
1 A       2000  40000
2 A       2005  42000
3 A       2010  44000
4 B       2000  38000
5 B       2005  40000
6 B       2010  43000
7 C       2000  52000
8 C       2005  52100
9 C       2010  52500

このように、望んだ形式のデータに一発で変換できる。

これを横長に戻してみよう。(教科書1刷で紹介されているtidyr::spread() の代わりに、)tidyr::pivot_wider() を使おう。

GDP_wide <- GDP_long |>  
    pivot_wider(names_from = year,    # 横長にした後の列を区別する変数
                names_prefix = "gdp", # 横長にした後の変数名の冒頭につける文字列(オプション)
                values_from = gdp)    # 縦長から横長に分配する値
GDP_wide
# A tibble: 3 × 4
  country gdp2000 gdp2005 gdp2010
  <chr>     <dbl>   <dbl>   <dbl>
1 A         40000   42000   44000
2 B         38000   40000   43000
3 C         52000   52100   52500

このように、元の横長データに戻すことができる。

pivot_longer()pivot_wider() を比較して、対応関係を理解しよう。

自分でデータフレームを作りたいときは、tibble::tibble() を使う。

newd <- tibble(id = 1:100,
               x = rnorm(100, mean = 10, sd = 2)) |> 
    mutate(y = 1.2 + 0.8 * x + rnorm(100, mean = 0, sd = 1))
glimpse(newd)
Rows: 100
Columns: 3
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, …
$ x  <dbl> 12.024695, 12.288869, 7.033155, 8.856460, 10.349913, 12.129229, 11.…
$ y  <dbl> 10.543795, 11.870085, 7.612501, 7.491888, 9.963130, 11.272057, 9.40…

複数のデータセットを結合する方法については、教科書第5章と宋・矢内『私たちのR』第14章を参照されたい。