第4回講義資料
記述統計
スライド
セットアップ
まず、本日の実習で使用するパッケージを読み込む。
当該パッケージがインストールされていない場合、以下のようなメッセージが出力される。
Error in library(パッケージ名) : there is no package called ‘パッケージ名’
この場合、install.packages("パッケージ名")
でパッケージをインストールしてから読み込もう。
パッケージは1回インストールしておけば、当該サーバーにはずっと残るため、今後、インストールは不要で、library()
で読み込むだけで良い。したがって、インストールはコードのスクリプトファイルに書く必要はなく、コンソールで入力して良い。ただし、別のサーバーを使う場合はもう一度インストールする必要がある。
ただし、当該パッケージがインストールされているかが分からない場合もあろう。あるいは、インストールされているにも関わらず、再インストールしてしまう可能性もある。パッケージによってはインストールに数分かかる場合もあるのでこれは非常に非効率的である。ここで便利なものが{pacman}パッケージだ。{pacman}パッケージがインストールされている場合、p_load()
関数でパッケージを読み込むことができる。p_load()
関数は{pacman}パッケージが提供する関数であるため、予めlibrary(pacman)
で{pacman}パッケージを読み込む必要があるが、パッケージ名::関数名()
でパッケージを読み込まずに特定パッケージ内の関数を呼び出すこともできる。
一つの関数内に複数のパッケージが同時に読み込めるといったメリットも大きいが、{pacman}最大の特徴は「インストールされていない場合、インストールしてから読み込む」ことだ。一旦、{pacman}をインストールしておけば大変便利になる。
続いてデータを読み込もう。実習に使用するデータはdescstat_data.csv
であり、LMSから入手可能だ。.csv
形式データを読み込む関数はread_csv()
であり、()
内にはパスを含むファイル名を入力する。パス+ファイル名は必ず"
で囲むこと。たとえば、プロジェクト・フォルダー内のData
フォルダー内のdescstat_data.csv
ファイルなら、"Data/descstat_data.csv"
と入力する。また、read_csv()
だけだとデータが読み込まれて出力されるだけで終わる。つまり、現在の作業環境内に残らない。作業環境にデータを格納するためには<-
演算子を使用する。ここではデータを読み込み、raw_df
という名のオブジェクトとして作業環境内に格納しておこう。
パス(path)とは何かについてよく分からない人は授業後でも良いので必ず「ファイル・システム」を精読すること。
データの中身を見るためにはオブジェクト名のみ入力すれば良い。
# A tibble: 3,000 × 48
USER_ID Q1 Q2 Q3 Q4 Q5_1 Q5_2 Q5_3 Q5_4 Q5_5 Q5_6 Q5_7 Q5_8 Q5_9 Q5_10 Q5_11
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 3 3 1 1 80 80 70 50 40 20 50 45 20 30 30
2 2 2 2 2 8 0 25 30 30 60 30 10 20 20 10 50
3 3 3 1 1 8 80 10 0 0 0 0 75 0 0 0 0
4 4 3 3 1 1 100 50 0 0 50 0 100 50 0 0 50
5 5 3 3 2 3 70 40 40 50 30 20 70 40 40 50 30
6 6 3 1 1 1 100 0 0 0 0 0 100 0 0 0 0
7 7 3 3 1 6 100 10 20 10 10 10 50 10 20 20 10
8 8 3 1 1 6 80 0 60 55 0 0 90 0 5 10 0
9 9 3 1 1 1 100 50 100 75 50 25 100 50 75 75 50
10 10 3 3 1 8 25 25 25 25 55 50 50 20 25 30 55
# ℹ 2,990 more rows
# ℹ 32 more variables: Q5_12 <dbl>, Q6_1 <dbl>, Q6_2 <dbl>, Q6_3 <dbl>, Q6_4 <dbl>, Q6_5 <dbl>,
# Q7 <dbl>, Q8 <dbl>, Q9 <dbl>, Q10_1 <dbl>, Q10_2 <dbl>, Q10_3 <dbl>, Q10_4 <dbl>, Q10_5 <dbl>,
# Q10_6 <dbl>, Q10_7 <dbl>, Q10_8 <dbl>, Q11 <dbl>, Q12 <dbl>, Q12S1 <dbl>, Q13 <dbl>,
# Q13S1 <dbl>, Q13S2 <dbl>, Q14 <dbl>, Q14S1 <dbl>, Q15 <dbl>, Q15S1 <dbl>, Q15S2 <dbl>,
# Q61 <dbl>, gender <dbl>, age <dbl>, chiiki <dbl>
出力画面の最上段にはraw_df
の大きさが出力される。3,000 × 48
は「3000行、48列」の表形式データであることを意味する。非常に大きなデータであるため、この内容が一画面に収めることはできないだろう。read_csv()
で読み込まれたデータは画面に表示可能な範囲内でデータを出力してくれる。省略された列は出力画面の下段を見れば分かる。
raw_df
の変数名(列名)を確認するためには、names()
関数を使用する。
[1] "USER_ID" "Q1" "Q2" "Q3" "Q4" "Q5_1" "Q5_2" "Q5_3" "Q5_4"
[10] "Q5_5" "Q5_6" "Q5_7" "Q5_8" "Q5_9" "Q5_10" "Q5_11" "Q5_12" "Q6_1"
[19] "Q6_2" "Q6_3" "Q6_4" "Q6_5" "Q7" "Q8" "Q9" "Q10_1" "Q10_2"
[28] "Q10_3" "Q10_4" "Q10_5" "Q10_6" "Q10_7" "Q10_8" "Q11" "Q12" "Q12S1"
[37] "Q13" "Q13S1" "Q13S2" "Q14" "Q14S1" "Q15" "Q15S1" "Q15S2" "Q61"
[46] "gender" "age" "chiiki"
また、データの大きさはdim()
関数でも確認することができる。
最後に出力される画面の行数についてだが、デフォルトでは10行出力となっている。もし、15行を出力したい場合はprint()
関数を使用し、n
引数で指定することができる。
# A tibble: 3,000 × 48
USER_ID Q1 Q2 Q3 Q4 Q5_1 Q5_2 Q5_3 Q5_4 Q5_5 Q5_6 Q5_7 Q5_8 Q5_9 Q5_10 Q5_11
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 3 3 1 1 80 80 70 50 40 20 50 45 20 30 30
2 2 2 2 2 8 0 25 30 30 60 30 10 20 20 10 50
3 3 3 1 1 8 80 10 0 0 0 0 75 0 0 0 0
4 4 3 3 1 1 100 50 0 0 50 0 100 50 0 0 50
5 5 3 3 2 3 70 40 40 50 30 20 70 40 40 50 30
6 6 3 1 1 1 100 0 0 0 0 0 100 0 0 0 0
7 7 3 3 1 6 100 10 20 10 10 10 50 10 20 20 10
8 8 3 1 1 6 80 0 60 55 0 0 90 0 5 10 0
9 9 3 1 1 1 100 50 100 75 50 25 100 50 75 75 50
10 10 3 3 1 8 25 25 25 25 55 50 50 20 25 30 55
11 11 1 2 2 3 60 30 25 10 10 0 60 10 10 5 1
12 12 2 2 2 6 50 50 50 50 50 50 50 50 50 50 50
13 13 3 1 1 3 100 5 30 5 0 0 100 0 10 5 0
14 14 3 3 2 8 60 70 70 50 70 50 50 60 60 50 60
15 15 2 3 3 7 50 50 50 50 50 50 50 50 50 50 50
# ℹ 2,985 more rows
# ℹ 32 more variables: Q5_12 <dbl>, Q6_1 <dbl>, Q6_2 <dbl>, Q6_3 <dbl>, Q6_4 <dbl>, Q6_5 <dbl>,
# Q7 <dbl>, Q8 <dbl>, Q9 <dbl>, Q10_1 <dbl>, Q10_2 <dbl>, Q10_3 <dbl>, Q10_4 <dbl>, Q10_5 <dbl>,
# Q10_6 <dbl>, Q10_7 <dbl>, Q10_8 <dbl>, Q11 <dbl>, Q12 <dbl>, Q12S1 <dbl>, Q13 <dbl>,
# Q13S1 <dbl>, Q13S2 <dbl>, Q14 <dbl>, Q14S1 <dbl>, Q15 <dbl>, Q15S1 <dbl>, Q15S2 <dbl>,
# Q61 <dbl>, gender <dbl>, age <dbl>, chiiki <dbl>
データハンドリング
通常、データの分析の歳、読み込んだデータをすべて利用することはあまりない(クリーニング済みのデータならすべて使う)。したがって、分析を始める前に、分析に使用するデータのみを残しておいた方が効率的であろう。データハンドリングについては前期講義資料の「データハンドリング(第9〜11回)」、『私たちのR』の第13、14、15、16章を参照されたい。ここではまず、記述統計を出したい変数のみを残し、抽出後のデータをdf
という名の新しいオブジェクトとして作業環境内に格納する。select()
関数の使い方は『私たちのR』の第13章を参照すること。
Code 08
# A tibble: 3,000 × 8
ID Gender Age Education Voted VotedParty T_Jimin T_Minshin
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 69 4 1 7 50 30
2 2 2 47 3 2 NA 10 50
3 3 2 37 99 1 1 75 0
4 4 1 51 4 1 1 100 50
5 5 1 38 99 2 NA 70 30
6 6 1 71 2 1 1 100 0
7 7 1 47 3 1 7 50 10
8 8 1 71 2 1 1 90 0
9 9 1 75 4 1 1 100 50
10 10 2 66 3 1 2 50 55
# ℹ 2,990 more rows
続いて、投票参加有無を示すVoted
変数をリコーディングする。元のVoted
変数は1
と2
の値で構成されており、1
は「投票」、2
は「棄権」を意味する。このVoted
列を修正したい。具体的にはVoted
の元の値が1
なら1
に、それ以外なら0
に修正したい。「ある条件を満たせばX、それ以外はYを返す」場合はif_else()
関数が有効である。if_else()
関数には3つの引数が必要であり、「1. 条件文」、「2. 条件が満たされた場合の戻り値」、「3. 条件が満たされない場合の戻り値」だ。Voted
が1
か否かを判定する条件文はVoted == 1
(=
でなく、==
であることに注意)であるため、if_else(Voted == 1, 1, 0)
となる(元の値が数値型でなく、文字型である場合は値を"
で囲むこと)。このリコーディングの結果をVoted
に上書きしたい。特定の列を修正したり、追加する関数はmutate()
だ。mutate()
内での書き方はmutate(修正/追加したい変数 = 修正内容)
である(ここは==
でなく=
であることに注意)。
また、Education
変数もリコーディングする。Education
は1以上4以下の整数のみをとる変数であるが、99という値も含まれている。この99は欠損値を意味している(どの値が欠損値を意味するかはデータによって異なる。自分が作成したデータでない場合、必ずコードブックに目を通しておこう)。これを99のままにすると、分析上、大きな問題を招きかねない。したがって、予め99を欠損値(NA
)に変更しておく必要がある。つまり、Education
の値が99なら(Education == 99
)NA
を、それ以外の場合は元のEducation
の値をとるようにリコーディングする。
以上の手順は以下のように記述する。df
を上書きしないと変更内容が保存されないため、上書きも忘れずに1。
Code 09
# A tibble: 3,000 × 8
ID Gender Age Education Voted VotedParty T_Jimin T_Minshin
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 69 4 1 7 50 30
2 2 2 47 3 0 NA 10 50
3 3 2 37 NA 1 1 75 0
4 4 1 51 4 1 1 100 50
5 5 1 38 NA 0 NA 70 30
6 6 1 71 2 1 1 100 0
7 7 1 47 3 1 7 50 10
8 8 1 71 2 1 1 90 0
9 9 1 75 4 1 1 100 50
10 10 2 66 3 1 2 50 55
# ℹ 2,990 more rows
それではこの変数らの記述統計量を計算してみよう。
記述統計
記述統計量(descriptive statistics)とはある変数が持つ情報を要約した数値である。例えば、df
のAge
列は回答者の年齢の変数である。この回答者たちの年齢について語る時、「このデータの回答者の年齢は69、47、37、51、…、18歳ですよ」という人はいないだろう。4-5人分のデータならまだしも、3000人の回答者ならあり得ない。我々は普段、「このデータの回答者の年齢はだいたいXX歳ですよ」とか、「真ん中の年齢はYY歳ですよ」と言うだろう。また、年齢の格差/ばらつきを語るときも標準偏差や範囲(「18歳から75歳までいますよ」など)を言うのが普通であろう。このように元の長い情報を一つの数値として要約したものが記述統計量である。
Rには記述統計量を計算するいくつかの関数が用意されている。
mean()
: 平均値median()
: 中央値var()
: 不偏分散sd()
: 不偏分散の平方根(いわゆる「標準偏差」)min()
、max()
: 最小値と最大値
たとえば、df
のAge
列(df$Age
)の平均値は以下のように計算する。na.rm = TRUE
は「もしdf$Age
に欠損値がある場合、それは除外して平均値を計算する」ことを意味する。
同じやり方で中央値(median()
)、最小値(min()
)、最大値(max()
)などが計算できる。しかし、本講義ではtidyverseパッケージ群を積極的に活用しているため、ここからは{dplyr}パッケージ(tidyverseを構成するパッケージの一つであり、{tidyverse}を読み込むと自動的に読み込まれる)のsummarise()
関数を使用する。summarise()
関数の詳細については、『私たちのR』の第14章を参照すること。ここではAge
変数の平均値、中央値、標準偏差、最小値、最大値、有効ケース数を計算し、それぞれMean
、Median
、SD
、Min
、Max
、N
という名の列として出力してみよう。
Code 11
# A tibble: 1 × 6
Mean Median SD Min Max N
<dbl> <dbl> <dbl> <dbl> <dbl> <int>
1 47.3 47 15.6 18 18 3000
有効ケース数(欠損していないケースの数)を計算する方法がやや面倒である。これはまずis.na()
関数を使って、当該変数が欠損していればTRUE
、そうでなければFALSE
と判定する。そしてis.na()
の前には否定演算子!
が付いている。つまり、is.na()
から得られた結果が逆となり、欠損していればFALSE
、値があればTRUE
になる。RにおいてTRUE
は1、FALSE
は0扱いとなるので、この合計(sum()
)を求めることで欠損していないケースの数が計算できるようになる。
名目変数の場合
これまでの内容は変数が連続変数(continuous variable)に限った話である。名目変数(categorical variable)の場合、平均値などは存在しない。100円と1万円の平均値は計算できるものの、男性と女性の平均値や北海道と鹿児島の平均値などはあり得ないからだ。しかし、名目変数でもデータ分析に使われる場面は多く、分析に使われる以上、記述統計量をしっかりと掲載すべきである。
名目変数の記述する簡単な方法としては度数分布表がある。たとえば、df
の場合、性別(Gender
)は男性(=1)と女性(=2)で構成されている。つまり、2つの要素(levels)で構成される変数だ。度数分布表は各要素がいくつあるかを示したものであり、table()
関数で簡単に確認することができる。
また、{dplyr}を使う場合、count()
関数を使用すれば良い。
しかし、連続変数用の記述統計表と名目変数用の度数分布表を分けることは非効率的である。分析に用いられる名目変数が数が多いと尚更だ。できれば名目変数も連続変数と同じ表で記述統計量を出した方が良いだろう。そのためには名目変数をダミー変数として変換すれば、平均値や標準偏差などが計算できるようになる。
ダミー変数は0と1のみで構成される変数である。たとえば、性別変数(Gender
列)は名目変数であるが、現在、1(男性)と2(女性)の2つの値で構成されている。この変数を男性ダミー変数と女性ダミー変数といった2つの変数に変換することである。男性ダミー変数はGender
の値が1なら、つまり当該回答者が男性(=1)なら1の値を、それ以外の場合は0の値をとる。女性ダミー変数の場合、当該回答者が女性(=2)なら1の値を、それ以外の場合は0の値をとる。以下の 表 1 はダミー変数のイメージである。 表 1 (a) の「出身」変数は普通の文字型変数であるが、この変数をダミー変数にすると 表 1 (b) の「早稲田」、「学習院」のようなダミー変数である。このようにダミー変数は0と1のみで構成される変数であり、通常、一つのダミー変数が1であれば他のダミー変数は0となる。
氏名 | 出身 |
---|---|
橋本 | 慶應 |
小渕 | 早稲田 |
森 | 早稲田 |
小泉 | 慶應 |
安倍 | 成蹊 |
福田 | 早稲田 |
麻生 | 学習院 |
鳩山 | 東京 |
菅 | 東工 |
野田 | 早稲田 |
菅 | 法政 |
岸田 | 早稲田 |
石破 | 慶應 |
氏名 | 早稲田 | 慶應 | 学習院 | 東京 | 東工 | 成蹊 | 法政 |
---|---|---|---|---|---|---|---|
橋本 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
小渕 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
森 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
小泉 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
安倍 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
福田 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
麻生 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
鳩山 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
菅 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
野田 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
菅 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
岸田 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
石破 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
それでは、if_else()
関数を使って男性ダミー変数(Male
)と女性ダミー変数(Female
)を作ってみよう。このダミー変数はGender
列の後ろにし、df2
という名のオブジェクトとして格納する。
Code 14
# A tibble: 3,000 × 10
ID Gender Male Female Age Education Voted VotedParty T_Jimin T_Minshin
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 0 1 69 4 1 7 50 30
2 2 2 0 1 47 3 0 NA 10 50
3 3 2 0 1 37 NA 1 1 75 0
4 4 1 1 0 51 4 1 1 100 50
5 5 1 1 0 38 NA 0 NA 70 30
6 6 1 1 0 71 2 1 1 100 0
7 7 1 1 0 47 3 1 7 50 10
8 8 1 1 0 71 2 1 1 90 0
9 9 1 1 0 75 4 1 1 100 50
10 10 2 0 1 66 3 1 2 50 55
# ℹ 2,990 more rows
df2
にはもう一つの名目変数がある。それは投票先を意味するVotedParty
変数だ。VotedParty
は1から7までの整数で構成されている。VotedParty
の値が1なら自民党に投票、2なら民進党に投票、…といった変数であり、これは計7個のダミー変数となる。
Code 15
df2 <- df2 |>
mutate(VotedParty_Jimin = if_else(VotedParty == 1, 1, 0),
VotedParty_Minshin = if_else(VotedParty == 2, 1, 0),
VotedParty_Komei = if_else(VotedParty == 3, 1, 0),
VotedParty_Ishin = if_else(VotedParty == 4, 1, 0),
VotedParty_Kyosan = if_else(VotedParty == 5, 1, 0),
VotedParty_Etc = if_else(VotedParty == 6, 1, 0),
VotedParty_DK = if_else(VotedParty == 7, 1, 0),
.after = VotedParty)
df2
# A tibble: 3,000 × 17
ID Gender Male Female Age Education Voted VotedParty VotedParty_Jimin VotedParty_Minshin
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 0 1 69 4 1 7 0 0
2 2 2 0 1 47 3 0 NA NA NA
3 3 2 0 1 37 NA 1 1 1 0
4 4 1 1 0 51 4 1 1 1 0
5 5 1 1 0 38 NA 0 NA NA NA
6 6 1 1 0 71 2 1 1 1 0
7 7 1 1 0 47 3 1 7 0 0
8 8 1 1 0 71 2 1 1 1 0
9 9 1 1 0 75 4 1 1 1 0
10 10 2 0 1 66 3 1 2 0 1
# ℹ 2,990 more rows
# ℹ 7 more variables: VotedParty_Komei <dbl>, VotedParty_Ishin <dbl>, VotedParty_Kyosan <dbl>,
# VotedParty_Etc <dbl>, VotedParty_DK <dbl>, T_Jimin <dbl>, T_Minshin <dbl>
あとはGender
とVotedParty
列は不要なので、こちらを除外する。
# A tibble: 3,000 × 15
ID Male Female Age Education Voted VotedParty_Jimin VotedParty_Minshin VotedParty_Komei
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 0 1 69 4 1 0 0 0
2 2 0 1 47 3 0 NA NA NA
3 3 0 1 37 NA 1 1 0 0
4 4 1 0 51 4 1 1 0 0
5 5 1 0 38 NA 0 NA NA NA
6 6 1 0 71 2 1 1 0 0
7 7 1 0 47 3 1 0 0 0
8 8 1 0 71 2 1 1 0 0
9 9 1 0 75 4 1 1 0 0
10 10 0 1 66 3 1 0 1 0
# ℹ 2,990 more rows
# ℹ 6 more variables: VotedParty_Ishin <dbl>, VotedParty_Kyosan <dbl>, VotedParty_Etc <dbl>,
# VotedParty_DK <dbl>, T_Jimin <dbl>, T_Minshin <dbl>
これで名目変数も連続変数と同じやり方で記述統計量が計算できる。
{fastDummies}の利用
しかし、以上の作業はかなり面倒だろう。7個の変数でも大変だが、たとえば回答者の都道府県があれば、計47行のコードを書く必要がある。このように面倒なダミー変数の作成を{fastuDummies}パッケージを使えばたった数行のコードでダミー化ができる。手順は以下の通りである。
- 名目変数をfactor型変数へ変換する。
- {fastDummies}パッケージの
dummy_cols()
関数でダミー化する。 - 生成された列を適宜修正する(変数名や位置など)。
それではまず、df
のGender
とVotedParty
列をfactor化してみよう。Gender
の場合、値が1なら"Male"
、2なら"Female"
を付ける。VotedParty
は値が1なら"Jimin"
、2なら"Minshin"
、3なら"Komei"
、4なら"Ishin"
、5なら"Kyosan"
、6なら"Etc"
(その他の政党)、7なら"DK"
(覚えていない/答えたくない)とする。修正後、df
はdf3
という名の新しいオブジェクトとして作業環境内に格納する。
Code 17
# A tibble: 3,000 × 8
ID Gender Age Education Voted VotedParty T_Jimin T_Minshin
<dbl> <fct> <dbl> <dbl> <dbl> <fct> <dbl> <dbl>
1 1 Female 69 4 1 DK 50 30
2 2 Female 47 3 0 <NA> 10 50
3 3 Female 37 NA 1 Jimin 75 0
4 4 Male 51 4 1 Jimin 100 50
5 5 Male 38 NA 0 <NA> 70 30
6 6 Male 71 2 1 Jimin 100 0
7 7 Male 47 3 1 DK 50 10
8 8 Male 71 2 1 Jimin 90 0
9 9 Male 75 4 1 Jimin 100 50
10 10 Female 66 3 1 Minshin 50 55
# ℹ 2,990 more rows
続いて、{fastDummies}のdummy_cols()
関数でGender
とVotedParty
をダミー変数に変換する。第一引数はダミー変数にしたい変数の名前を"
で囲んだものを入れる。2つ以上の変数をダミー化するならc()
でまとめる。続いて、ignore_na = TRUE
を指定する。これを指定しない場合、「欠損か否か」のダミー変数まで作成される。つづいて、元の変数(Gender
とVotedParty
)を除外する。
Code 18
# A tibble: 3,000 × 15
ID Age Education Voted T_Jimin T_Minshin Gender_Male Gender_Female VotedParty_Jimin
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int> <int>
1 1 69 4 1 50 30 0 1 0
2 2 47 3 0 10 50 0 1 NA
3 3 37 NA 1 75 0 0 1 1
4 4 51 4 1 100 50 1 0 1
5 5 38 NA 0 70 30 1 0 NA
6 6 71 2 1 100 0 1 0 1
7 7 47 3 1 50 10 1 0 0
8 8 71 2 1 90 0 1 0 1
9 9 75 4 1 100 50 1 0 1
10 10 66 3 1 50 55 0 1 0
# ℹ 2,990 more rows
# ℹ 6 more variables: VotedParty_Minshin <int>, VotedParty_Komei <int>, VotedParty_Ishin <int>,
# VotedParty_Kyosan <int>, VotedParty_Etc <int>, VotedParty_DK <int>
これでダミー化は完了だ。ここで更に変数名を変更し、位置を調整してみよう。たとえば、Gender_Male
はMale
に、Gender_Female
はFemale
に変更し、ID
列の後ろへ移動させるとしよう。この場合、relocate()
関数を使用する。列名を変更する場合は新しい変数名 = 既存の変数名
と指定し、.after
、あるいは.before
で位置を指定する。
# A tibble: 3,000 × 15
ID Male Female Age Education Voted T_Jimin T_Minshin VotedParty_Jimin VotedParty_Minshin
<dbl> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <int> <int>
1 1 0 1 69 4 1 50 30 0 0
2 2 0 1 47 3 0 10 50 NA NA
3 3 0 1 37 NA 1 75 0 1 0
4 4 1 0 51 4 1 100 50 1 0
5 5 1 0 38 NA 0 70 30 NA NA
6 6 1 0 71 2 1 100 0 1 0
7 7 1 0 47 3 1 50 10 0 0
8 8 1 0 71 2 1 90 0 1 0
9 9 1 0 75 4 1 100 50 1 0
10 10 0 1 66 3 1 50 55 0 1
# ℹ 2,990 more rows
# ℹ 5 more variables: VotedParty_Komei <int>, VotedParty_Ishin <int>, VotedParty_Kyosan <int>,
# VotedParty_Etc <int>, VotedParty_DK <int>
続いて、VotedParty_Jimin
からVotedParty_DK
までの列をVoted
列の後ろへ動かしてみよう。変数選択の場合、:
演算子を使うと「〜から〜まで」の指定ができる。
# A tibble: 3,000 × 15
ID Male Female Age Education Voted VotedParty_Jimin VotedParty_Minshin VotedParty_Komei
<dbl> <int> <int> <dbl> <dbl> <dbl> <int> <int> <int>
1 1 0 1 69 4 1 0 0 0
2 2 0 1 47 3 0 NA NA NA
3 3 0 1 37 NA 1 1 0 0
4 4 1 0 51 4 1 1 0 0
5 5 1 0 38 NA 0 NA NA NA
6 6 1 0 71 2 1 1 0 0
7 7 1 0 47 3 1 0 0 0
8 8 1 0 71 2 1 1 0 0
9 9 1 0 75 4 1 1 0 0
10 10 0 1 66 3 1 0 1 0
# ℹ 2,990 more rows
# ℹ 6 more variables: VotedParty_Ishin <int>, VotedParty_Kyosan <int>, VotedParty_Etc <int>,
# VotedParty_DK <int>, T_Jimin <dbl>, T_Minshin <dbl>
むろん、:
ではなく、starts_with()
関数で変数選択もできる。いずれも"VotedParty_"
で始まる変数名なので、starts_with("VotedParty_")
と書けば、VotedParty_
で始まる全変数が選択される。
{summarytools}の利用
記述統計量は実証分析の論文において必須であり、多くの場合、最初の表として登場する。人によっては記述統計量の表をTable Oneとも呼ぶのもこれが理由である。記述統計量を示すことが重要だというのは、表作成の需要が高いことを意味し、高い需要はかならず供給を生み出す。Rにおいても簡単に記述統計量をまとめてくれるパッケージが多数あり、ここでは{summarytools}パッケージをを紹介する。
{summarytools}には記述統計量をまとめてくれる関数が複数あるが、ここではdescr()
関数を使用する。使い方は非常に単純で、()
内にデータのオブジェクト名を入力するだけだ。むろん、パイプ演算子(|>
)も使える。パイプ演算子は今後、毎回登場するので、忘れた人はミクロ政治データ分析実習のhttps://www.jaysong.net/r4ps/materials/micro/handling1.html、または『私たちのR』の第13章を参照すること。
Descriptive Statistics
df
N: 3000
Age Education Gender ID T_Jimin T_Minshin Voted VotedParty
----------------- --------- ----------- --------- --------- --------- ----------- --------- ------------
Mean 47.34 3.11 1.50 1500.50 41.13 34.25 0.74 2.94
Std.Dev 15.63 0.89 0.50 866.17 28.02 25.95 0.44 2.21
Min 18.00 1.00 1.00 1.00 0.00 0.00 0.00 1.00
Q1 34.00 2.00 1.00 750.50 20.00 10.00 0.00 1.00
Median 47.00 3.00 2.00 1500.50 50.00 40.00 1.00 2.00
Q3 61.00 4.00 2.00 2250.50 60.00 50.00 1.00 5.00
Max 75.00 4.00 2.00 3000.00 100.00 100.00 1.00 7.00
MAD 19.27 1.48 0.00 1111.95 29.65 29.65 0.00 1.48
IQR 27.00 2.00 1.00 1499.50 40.00 40.00 1.00 4.00
CV 0.33 0.29 0.33 0.58 0.68 0.76 0.60 0.75
Skewness -0.03 -0.38 -0.01 0.00 0.02 0.16 -1.07 0.82
SE.Skewness 0.04 0.05 0.04 0.04 0.04 0.04 0.04 0.05
Kurtosis -1.14 -1.28 -2.00 -1.20 -0.83 -0.81 -0.85 -0.82
N.Valid 3000.00 2913.00 3000.00 3000.00 3000.00 3000.00 3000.00 2208.00
Pct.Valid 100.00 97.10 100.00 100.00 100.00 100.00 100.00 73.60
よく使う平均値(Mean)、標準偏差(Std.Dev)など以外にも第一四分位数(Q1)や四分位範囲(IQR)、歪度(Skewness)などまで出力される。実際はこれら全てを掲載するケースはあまりない。ここでは平均値("mean"
)、標準偏差("sd"
)、最小値("min"
)、最大値("max"
)、有効ケース数("n.vailid"
)のみに絞ってみよう。出力する記述統計量はstats
引数で指定できる。
Descriptive Statistics
df
N: 3000
Age Education Gender ID T_Jimin T_Minshin Voted VotedParty
------------- --------- ----------- --------- --------- --------- ----------- --------- ------------
Mean 47.34 3.11 1.50 1500.50 41.13 34.25 0.74 2.94
Std.Dev 15.63 0.89 0.50 866.17 28.02 25.95 0.44 2.21
Min 18.00 1.00 1.00 1.00 0.00 0.00 0.00 1.00
Max 75.00 4.00 2.00 3000.00 100.00 100.00 1.00 7.00
N.Valid 3000.00 2913.00 3000.00 3000.00 3000.00 3000.00 3000.00 2208.00
ただし、まだ気になる点がある。それは行と列が普段見る記述統計量の表と逆だということだ。これはtranspose = TRUE
を追加することで対応できる。また、変数の順番もdf
内の順番でなく、勝手にアルファベット順になっている。これをdf
内の順番にするためにはorder = "p"
を追加すれば良い。
Code 24
Descriptive Statistics
df
N: 3000
Mean Std.Dev Min Max N.Valid
---------------- --------- --------- ------- --------- ---------
ID 1500.50 866.17 1.00 3000.00 3000.00
Gender 1.50 0.50 1.00 2.00 3000.00
Age 47.34 15.63 18.00 75.00 3000.00
Education 3.11 0.89 1.00 4.00 2913.00
Voted 0.74 0.44 0.00 1.00 3000.00
VotedParty 2.94 2.21 1.00 7.00 2208.00
T_Jimin 41.13 28.02 0.00 100.00 3000.00
T_Minshin 34.25 25.95 0.00 100.00 3000.00
最後にID
行の記述統計量を削除してみよう。これは回答者の識別番号であって、その平均値や標準偏差はどうでもいい。そのためにはdf
をdescr()
を渡す前にselect()
関数を使ってID
列を除外してから渡せば良いだろう。Gender
とVotedParty
もまた名目変数であるが、ここではとりあえず放置しておく。
Code 25
Descriptive Statistics
Mean Std.Dev Min Max N.Valid
---------------- ------- --------- ------- -------- ---------
Gender 1.50 0.50 1.00 2.00 3000.00
Age 47.34 15.63 18.00 75.00 3000.00
Education 3.11 0.89 1.00 4.00 2913.00
Voted 0.74 0.44 0.00 1.00 3000.00
VotedParty 2.94 2.21 1.00 7.00 2208.00
T_Jimin 41.13 28.02 0.00 100.00 3000.00
T_Minshin 34.25 25.95 0.00 100.00 3000.00
それでは名目変数を含めた記述統計表を作成してみよう。df
のGender
とVotedParty
変数のダミー化を済ませてからdescr()
に渡せば良い。記述統計表はdesc_stat
という名のオブジェクトとして作業環境内に格納する。
Code 26
desc_stat <- df |>
mutate(Gender = factor(Gender, levels = c(1, 2),
labels = c("Male", "Female")),
VotedParty = factor(VotedParty, levels = 1:7,
labels = c("Jimin", "Minshin", "Komei", "Ishin",
"Kyosan", "Etc", "DK"))) |>
dummy_cols(c("Gender", "VotedParty"), ignore_na = TRUE,
# 以下の引数を追加すると元の変数が自動的に削除される
remove_selected_columns = TRUE) |>
# Gender_MaleとGender_Femaleの変数名を変更し、ID列の後ろに移動させる。
relocate(Male = Gender_Male,
Female = Gender_Female,
.after = ID) |>
relocate(starts_with("VotedParty"), .after = Voted) |>
select(-ID) |>
descr(stats = c("mean", "sd", "min", "max", "n.valid"),
transpose = TRUE, order = "p")
desc_stat
Descriptive Statistics
Mean Std.Dev Min Max N.Valid
------------------------ ------- --------- ------- -------- ---------
Male 0.50 0.50 0.00 1.00 3000.00
Female 0.50 0.50 0.00 1.00 3000.00
Age 47.34 15.63 18.00 75.00 3000.00
Education 3.11 0.89 1.00 4.00 2913.00
Voted 0.74 0.44 0.00 1.00 3000.00
VotedParty_Jimin 0.40 0.49 0.00 1.00 2208.00
VotedParty_Minshin 0.20 0.40 0.00 1.00 2208.00
VotedParty_Komei 0.05 0.22 0.00 1.00 2208.00
VotedParty_Ishin 0.10 0.30 0.00 1.00 2208.00
VotedParty_Kyosan 0.08 0.27 0.00 1.00 2208.00
VotedParty_Etc 0.01 0.10 0.00 1.00 2208.00
VotedParty_DK 0.16 0.37 0.00 1.00 2208.00
T_Jimin 41.13 28.02 0.00 100.00 3000.00
T_Minshin 34.25 25.95 0.00 100.00 3000.00
{gt}パッケージを使えば、よりまとまった表として出力できる。興味のある履修者はやってみよう。{gt}パッケージのチュートリアルおよびレファレンスは公式ページを参照すること。
Code 27
Mean | Std.Dev | Min | Max | N.Valid | |
---|---|---|---|---|---|
Male | 0.497 | 0.500 | 0 | 1 | 3000 |
Female | 0.503 | 0.500 | 0 | 1 | 3000 |
Age | 47.340 | 15.628 | 18 | 75 | 3000 |
Education | 3.114 | 0.893 | 1 | 4 | 2913 |
Voted | 0.736 | 0.441 | 0 | 1 | 3000 |
VotedParty_Jimin | 0.399 | 0.490 | 0 | 1 | 2208 |
VotedParty_Minshin | 0.199 | 0.399 | 0 | 1 | 2208 |
VotedParty_Komei | 0.051 | 0.220 | 0 | 1 | 2208 |
VotedParty_Ishin | 0.100 | 0.300 | 0 | 1 | 2208 |
VotedParty_Kyosan | 0.078 | 0.269 | 0 | 1 | 2208 |
VotedParty_Etc | 0.011 | 0.104 | 0 | 1 | 2208 |
VotedParty_DK | 0.163 | 0.369 | 0 | 1 | 2208 |
T_Jimin | 41.130 | 28.015 | 0 | 100 | 3000 |
T_Minshin | 34.248 | 25.947 | 0 | 100 | 3000 |
グループごとの記述統計
可視化
注
まずは上書きせず出力結果を確認し、問題ない場合は上書きするようにしよう。間違ったコードで上書きをした場合、最初のコードからもう一度実行すること。↩︎