tidyverseパッケージを使うので、インストールしていない場合は、まずインストールする。 インストール済みの者は次のコマンドは実行しない。また、このコマンドは一度しか使わないので、Consoleに直接入力する。
インストールが済んだら、パッケージを読み込む。
tidyverse は単一のパッケージではなく、複数のパッケージを含むパッケージ群であり、dplyr やreadr、ggplot2など、この授業で頻繁に使ういくつかのパッケージを一気に読み込んでくれる。
今後授業で扱うデータを保存する場所として、プロジェクト内に data という名前のディレクトリ(フォルダ)を作ろう。 既に data フォルダがある場合は実行しなくてよい。このコマンドも一度しか使わないので、Consoleに直接入力する。
実行すると、右下のFiles タブに、dataというディレクトリ(フォルダ)ができるはずだ。
データの形式として最もよく使われるものの1つが、CSV (comma separated values) という形式である。これはただのテキストファイルであり、値がカンマで区切られているだけである。
この形式のファイルの中身を理解するために、 fake-data-01.csv をダウンロードしてファイルの中身を確認してみよう。
ファイルのダウンロードは、download.file()
で行う。この関数で指定するのは、url(データがある場所のURL)とdestfile(ダウンロードしたファイルをどこに何という名前で保存するか)である。次のコマンドを実行してみよう。
download.file(url = "http://yukiyanai.github.io/jp/classes/econometrics1/contents/data/fake-data-01.csv",
destfile = "data/fake-data-01.csv")
このコマンドを実行すると、指定したURLにあるファイルがダウンロードされ、dataディレクトリの中に fake-data-01.csv という名前で保存される。上でのコマンドのdestfile では、まずdata というフォルダにファイルを保存することを、data/ で示し、その後にファイル名を指定している。
ファイルがダウンロードできたら、Windowsのエクスプローラ(Macのファインダ)でこのファイルを右クリック(副クリックまたは control を押しながらクリック)し、「プログラムから開く」を選び、Excel で開いてみよう。見慣れた形式(スプレッドシート)でデータが見えるはずだ。確認できたらExcelを閉じよう。
次に、同じファイルを同様に「プログラムから開く」でメモ帳で開いてみよう。ファイルの中身が見えるはずだ。CSV ファイルは、1行目は変数の名前、2行目以降は各行が1つの観測(このデータの場合は一人ひとりの個人)、各行で異なる変数の間にカンマがある(そのため、カンマ区切りデータと呼ばれる)という特徴がある。
この形式のメリットとして、
などがあげられる(注意:このファイルを Word 等のワープロソフトで編集しないように。余分な内容が追加されてデータの中身が変わってしまう。)。
Excel 等に自分でデータを打ち込んで新しいデータセットを作るときは、できるだけこのCSV 形式を選んだ方がよい。
CSV形式のデータは、readr パッケージの read_csv()
関数(以後の、このようにパッケージに含まれる関数は、二重コロンを使って readr::read_csv()
のように書く) でRに読み込むことができる。既に説明したとおり、readr パッケージはtidyverseに含まれるので、tidyverseを読み込んだ時点で読み込まれている。
## Parsed with column specification:
## cols(
## id = col_integer(),
## sex = col_character(),
## age = col_integer(),
## height = col_double(),
## weight = col_double(),
## income = col_integer()
## )
プロジェクト内の data という名前のディレクトリに入っていることを data/
の部分で示し、そのフォルダ内の fake-data-01.csv
を指定して開いている。 このとき、引用符を忘れないように注意する。引用符はシングル「’」でも、ダブル 「"」でもよい。
RStudio でデータを読み込むと、 EnvironmentタブのDataのところに読み込んだデータセットが表示される。
念のために中身を少しだけ確認しておこう。
## # A tibble: 6 x 6
## id sex age height weight income
## <int> <chr> <int> <dbl> <dbl> <int>
## 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
## # A tibble: 6 x 6
## id sex age height weight income
## <int> <chr> <int> <dbl> <dbl> <int>
## 1 95 female 21 165. 56.3 1339138
## 2 96 female 65 161. 46.8 6127136
## 3 97 female 45 161. 48.7 1062663
## 4 98 female 53 166. 64.2 10154200
## 5 99 female 43 158. 48.5 8287163
## 6 100 female 48 154. 42 1125390
Excel のデータは、.xlsx または .xls という拡張子で保存されている。 このデータをRで直接読む方法もあるが、ここではExcel 形式のデータをCSV形式に変換し、それを上で説明した方法で読むことにする。
例として、fake-data-03.xlsx を使う。まず、このデータをダウンロードし、Excel で開こう。
これを、CSV形式に変換し、プロジェクト内の data フォルダに保存する。そのために、以下を実行する。
保存できたら、RStudioのFilesタブで data フォルダをクリックし、fake-data-03.csv が保存されていることを確かめよう。
あとは、先ほどと同様の方法でデータを読めばいいので、
## Parsed with column specification:
## cols(
## id = col_integer(),
## sex = col_character(),
## age = col_integer(),
## height = col_double(),
## weight = col_double(),
## income = col_integer()
## )
とすればよい。RStudio のEnvironmentタブで、データが読み込めたこと(mycsv2というデータが追加されたこと)を確認しよう。
念のために中身を少しだけ確認しておこう。
## # A tibble: 6 x 6
## id sex age height weight income
## <int> <chr> <int> <dbl> <dbl> <int>
## 1 1 male 46 168. 72.1 2102061
## 2 2 male 22 177. 85.4 2729262
## 3 3 male 61 172. 81.8 1193016
## 4 4 male 48 170. 65.2 3014919
## 5 5 male 44 168. 66 3982087
## 6 6 male 23 161. 50.8 3702544
## # A tibble: 6 x 6
## id sex age height weight income
## <int> <chr> <int> <dbl> <dbl> <int>
## 1 95 female 47 150. 33.2 9814520
## 2 96 female 50 154. 49.8 2299483
## 3 97 female 37 160. 54.6 4912932
## 4 98 female 63 154. 47.3 3627498
## 5 99 female 49 145. 37.7 51329365
## 6 100 female 63 155. 43.4 14160139
ここまでで2つのデータセットを読み込んだので、RStudioの右上には、2つのデータセット、mycsv1 と mycsv2 が表示されているはずである。このように、Rには複数のデータを同時に利用できるというメリットがある。
これらのデータセットに含まれる変数を確認してみよう。
## [1] "id" "sex" "age" "height" "weight" "income"
## [1] "id" "sex" "age" "height" "weight" "income"
2つのデータセットに含まれる変数名は同じようである。
では、2つのデータはまったく同じものだろうか。ためしに、それぞれのデータセット身長 (height) の平均値を求めてみよう。
## [1] 163.746
## [1] 162.907
平均値は異なる。つまり、変数名は同じでも、データの中身は違うようだ。
このように、異なるデータセットが同じ名前の変数を含んでいることがあるので注意が必要だ。Rでは、$
という記号を使って データセット名$変数名
とすることで、同じ名前の変数でも、異なるデータセットに属している場合にはそれらを区別して利用することができる。
Stata のデータセットには、.dta という拡張子が付いている。
StataのファイルをRで読みたいときは、haven というパッケージに含まれる read_dta()
という関数を使う。(今後これを、haven::read_dta()
と表記する。他のパッケージに含まれる関数についても、`パッケージ名::関数名()
という書き方をする。)
例として、fake-data-stata.dta をダウンロードし、data フォルダに保存しよう。 これを読むには、haven パッケージが必要である。
RStudio の右上で、データが読み込めたことを確認しよう。
念のために中身も少しだけ確認しておこう。
## # A tibble: 6 x 6
## id sex age height weight income
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 1 male 31 167. 59.8 1094707
## 2 2 male 57 154. 51.4 370882
## 3 3 male 52 168. 61.2 12449508
## 4 4 male 46 179. 71.8 25811696
## 5 5 male 58 169. 70.5 1182427
## 6 6 male 49 155. 32.7 706000
## # A tibble: 6 x 6
## id sex age height weight income
## <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 95 female 33 161. 47.6 2694716
## 2 96 female 51 157. 55.9 1822781
## 3 97 female 46 161. 61.5 7372126
## 4 98 female 27 154. 52.9 4945325
## 5 99 female 58 163. 65.1 1983602
## 6 100 female 25 152. 38.7 699745
SPSS 形式のデータには、.savという拡張子が付いている。 Rでは、haven::read_sav()
(または haven::read_spss()
)で読み込める。
例として、fake-data-spss.sav をダウンロードし、data フォルダに保存しよう。 このファイルは、以下のコマンドで読み込める。
RStudio の右上で、データが読み込めたことを確認しよう。
念のために中身も少しだけ確認しておこう。
## # A tibble: 6 x 6
## id sex age height weight income
## <dbl> <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 1 67 168. 58.5 1659808.
## 2 2 1 57 167. 54.5 1550051
## 3 3 1 58 165. 62.9 3139595
## 4 4 1 40 172. 68.8 4563089
## 5 5 1 24 167. 59.8 1864069
## 6 6 1 59 173. 83.6 5311530
## # A tibble: 6 x 6
## id sex age height weight income
## <dbl> <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
## 1 95 2 28 162 53.4 1683968.
## 2 96 2 68 158. 53.4 12322588
## 3 97 2 48 157. 46.6 1901600
## 4 98 2 33 156. 52.9 7906638
## 5 99 2 59 160. 41.1 3333649
## 6 100 2 36 160. 47.4 658383
Rはこの他には様々な形式のデータを読むことができる。必要に応じて他の方法も解説するが、この授業で他の形式が必要になることはないはずである。
ここからは、教科書(今井 2018)第2章のRコードを整理する。教科書ではパッケージを使わずに分析がされているが、パッケージを使った方が簡単なコードが書けるので、パッケージを利用した分析法を説明する。
人種差別かあるかどうかを調べるために行われた実験のデータ resume.csv をプロジェクト内のdataディレクトリにダウンロードし、保存する。 データのダウンロードは、download.file
関数で行う。
download.file(url = "http://qss.princeton.press/student-files/CAUSALITY/resume.csv",
destfile = "data/resume.csv")
このファイルをreadr::read_csv()
で読み込み、resumeという名前のオブジェクトを作る。
## Parsed with column specification:
## cols(
## firstname = col_character(),
## sex = col_character(),
## race = col_character(),
## call = col_integer()
## )
データの中身を確認する。
## Observations: 4,870
## Variables: 4
## $ firstname <chr> "Allison", "Kristen", "Lakisha", "Latonya", "Carrie"...
## $ sex <chr> "female", "female", "female", "female", "female", "m...
## $ race <chr> "white", "white", "black", "black", "white", "white"...
## $ call <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
## firstname sex race
## Length:4870 Length:4870 Length:4870
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
## call
## Min. :0.00000
## 1st Qu.:0.00000
## Median :0.00000
## Mean :0.08049
## 3rd Qu.:0.00000
## Max. :1.00000
人種 (race) と連絡がきたかどうか (call) のクロス表を作る。
## 連絡
## 人種 0 1
## black 2278 157
## white 2200 235
周辺度数(各行、各列の合計)を加える。
## 連絡
## 人種 0 1 Sum
## black 2278 157 2435
## white 2200 235 2435
## Sum 4478 392 4870
審査通過率を計算する。
## [1] 0.08049281
人種ごとの審査通過率を計算する。
## # A tibble: 2 x 2
## race passage
## <chr> <dbl>
## 1 black 0.0645
## 2 white 0.0965
黒人らしい名前の審査通過率を計算する。そのために、dplyr::filter()
を使って、データフレーム一部を切り取る(dplyrパッケージはtidyverseに含まれている)。
## [1] 0.06447639
黒人のみのデータフレームを作る。
このデータフレームを使って審査通過率を計算する。
## [1] 0.06447639
黒人女性らしい名前の観測対象を残し、変数は call と firstname のみ残す。
resumeBf <- resume %>%
filter(race == "black", sex == "female") %>%
select(call, firstname)
head(resumeBf)
## # A tibble: 6 x 2
## call firstname
## <int> <chr>
## 1 0 Lakisha
## 2 0 Latonya
## 3 0 Kenya
## 4 0 Latonya
## 5 0 Aisha
## 6 0 Aisha
黒人男性のデータフレームを作る。
白人女性のデータフレームを作る。
白人男性のデータフレームを作る。
元のデータフレームの観測の数と比べる。
## [1] 4870
## [1] 4870
女性同士の人種格差を計算する。
## [1] 0.03264689
男性同士の人種格差を計算する。
## [1] 0.03040786
黒人女性であることを示すBlackFemaleという変数を作る。
人種と性別の組み合わせで4つのタイプに分類する type という変数を作る。
resume <- resume %>%
mutate(type = ifelse(BlackFemale == 1, "BlackFemale", NA)) %>%
mutate(type = ifelse(race == "black" & sex == "male",
"BlackMale", type),
type = ifelse(race == "white" & sex == "female",
"WhiteFemale", type),
type = ifelse(race == "white" & sex == "male",
"WhiteMale", type))
変数typeのクラスを確認する。
## [1] "character"
typeを因子に変える。
##
## BlackFemale BlackMale WhiteFemale WhiteMale
## 1886 549 1860 575
名前 (firstname) を因子型に変え、それぞれの名前の審査通過率を計算し、それを昇順に並べ替える。
resume %>%
mutate(firstname = factor(firstname)) %>%
group_by(firstname) %>%
summarize(passage = mean(call)) %>%
arrange(passage)
## # A tibble: 36 x 2
## firstname passage
## <fct> <dbl>
## 1 Aisha 0.0222
## 2 Rasheed 0.0299
## 3 Keisha 0.0383
## 4 Tremayne 0.0435
## 5 Kareem 0.0469
## 6 Darnell 0.0476
## 7 Tyrone 0.0533
## 8 Hakim 0.0545
## 9 Tamika 0.0547
## 10 Lakisha 0.055
## # ... with 26 more rows
データファイル social.csv をダウンロードしてdataディレクトリに保存する。
download.file(url = "http://qss.princeton.press/student-files/CAUSALITY/social.csv",
destfile = "data/social.csv")
データを読み込み、中身を確認する。
## Parsed with column specification:
## cols(
## sex = col_character(),
## yearofbirth = col_integer(),
## primary2004 = col_integer(),
## messages = col_character(),
## primary2006 = col_integer(),
## hhsize = col_integer()
## )
## Observations: 41,699
## Variables: 6
## $ sex <chr> "male", "female", "male", "female", "female", "mal...
## $ yearofbirth <int> 1941, 1947, 1951, 1950, 1982, 1981, 1959, 1956, 19...
## $ primary2004 <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0,...
## $ messages <chr> "Civic Duty", "Civic Duty", "Hawthorne", "Hawthorn...
## $ primary2006 <int> 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1,...
## $ hhsize <int> 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 2, 1, 2, 2, 1,...
異なるメッセージ (messages) を受け取ったグループの投票率を調べよう。
## # A tibble: 5 x 2
## messages mean
## <chr> <dbl>
## 1 Civic Duty 0.321
## 2 Control 0.311
## 3 Hawthorne 0.333
## 4 Neighbors 0.398
## 5 <NA> NA
コントロールグループの投票率。
各グループの投票率からコントロールグループの投票率を引く
## # A tibble: 5 x 2
## messages dif
## <chr> <dbl>
## 1 Civic Duty 0.0103
## 2 Control 0
## 3 Hawthorne 0.0215
## 4 Neighbors 0.0874
## 5 <NA> NA
年齢変数を作成する。
メッセージ別の年齢の平均値を確かめる。
## # A tibble: 5 x 2
## messages age
## <chr> <dbl>
## 1 Civic Duty 48.0
## 2 Control 48.3
## 3 Hawthorne 48.3
## 4 Neighbors 48.5
## 5 <NA> 30
メッセージ別のprimy2004の平均値を確かめる。
## # A tibble: 5 x 2
## messages primary2004
## <chr> <dbl>
## 1 Civic Duty 0.318
## 2 Control 0.323
## 3 Hawthorne 0.329
## 4 Neighbors 0.338
## 5 <NA> 0
メッセージ別のhhsize(世帯人数)の平均値を確かめる。
## # A tibble: 5 x 2
## messages hhsize
## <chr> <dbl>
## 1 Civic Duty 2.21
## 2 Control 2.20
## 3 Hawthorne 2.19
## 4 Neighbors 2.20
## 5 <NA> NA
データファイル minwage.csv をダウンロードしてdataディレクトリに保存する。
download.file(url = "http://qss.princeton.press/student-files/CAUSALITY/minwage.csv",
destfile = "data/minwage.csv")
データを読み込み、中身を確認する。
## Parsed with column specification:
## cols(
## chain = col_character(),
## location = col_character(),
## wageBefore = col_double(),
## wageAfter = col_double(),
## fullBefore = col_double(),
## fullAfter = col_double(),
## partBefore = col_double(),
## partAfter = col_double()
## )
## Observations: 358
## Variables: 8
## $ chain <chr> "wendys", "wendys", "burgerking", "burgerking", "kf...
## $ location <chr> "PA", "PA", "PA", "PA", "PA", "PA", "PA", "PA", "PA...
## $ wageBefore <dbl> 5.00, 5.50, 5.00, 5.00, 5.25, 5.00, 5.00, 5.00, 5.0...
## $ wageAfter <dbl> 5.25, 4.75, 4.75, 5.00, 5.00, 5.00, 4.75, 5.00, 4.5...
## $ fullBefore <dbl> 20.0, 6.0, 50.0, 10.0, 2.0, 2.0, 2.5, 40.0, 8.0, 10...
## $ fullAfter <dbl> 0.0, 28.0, 15.0, 26.0, 3.0, 2.0, 1.0, 9.0, 7.0, 18....
## $ partBefore <dbl> 20.0, 26.0, 35.0, 17.0, 8.0, 10.0, 20.0, 30.0, 27.0...
## $ partAfter <dbl> 36, 3, 18, 9, 12, 9, 25, 32, 39, 10, 20, 4, 13, 20,...
## chain location wageBefore wageAfter
## Length:358 Length:358 Min. :4.250 Min. :4.250
## Class :character Class :character 1st Qu.:4.250 1st Qu.:5.050
## Mode :character Mode :character Median :4.500 Median :5.050
## Mean :4.618 Mean :4.994
## 3rd Qu.:4.987 3rd Qu.:5.050
## Max. :5.750 Max. :6.250
## fullBefore fullAfter partBefore partAfter
## Min. : 0.000 Min. : 0.000 Min. : 0.00 Min. : 0.00
## 1st Qu.: 2.125 1st Qu.: 2.000 1st Qu.:11.00 1st Qu.:11.00
## Median : 6.000 Median : 6.000 Median :16.25 Median :17.00
## Mean : 8.475 Mean : 8.362 Mean :18.75 Mean :18.69
## 3rd Qu.:12.000 3rd Qu.:12.000 3rd Qu.:25.00 3rd Qu.:25.00
## Max. :60.000 Max. :40.000 Max. :60.00 Max. :60.00
PAとNJのデータフレームを分ける。
賃金が5.05ドル以下のファーストフード店の割合。
## [1] 0.9106529
## [1] 0.003436426
## [1] 0.05970149
## [1] 0.9402985
常勤労働者の割合を表す変数を作る。
minwageNJ <- minwageNJ %>%
mutate(fullPropAfter = fullAfter / (fullAfter + partAfter))
minwagePA <- minwagePA %>%
mutate(fullPropAfter = fullAfter / (fullAfter + partAfter))
平均の差を計算する。
## [1] 0.04811886
ファーストフード店の割合を確認する。
## .
## burgerking kfc roys wendys
## 0.4054983 0.2233677 0.2508591 0.1202749
## .
## burgerking kfc roys wendys
## 0.4626866 0.1492537 0.2238806 0.1641791
バーガーキングのみ取り出す。
minwageNJ.bk <- minwageNJ %>% filter(chain == "burgerking")
minwagePA.bk <- minwagePA %>% filter(chain == "burgerking")
常勤雇用の割合を比較する。
## [1] 0.03643934