1. 統計学の種類

  • 統計学は記述統計学 (descriptive statistics) と推測統計学 (inferential statistics) の二つに分類できる
統計学の種類 特徴
記述統計学: 統計量を使ってデータ傾向や性質をつかむ
推測統計学: 母集団の母数(母平均や母分散)を検定し推定する

記述統計学

  • 集めたデータの統計量(平均、分散、標準偏差など)を計算して、そのデータを我々が理解できるような形で記述し要約する
  • データの分布を明らかにすることで、データ傾向や性質をつかむための統計手法 

推測統計学

  • 入手可能な記述統計量を使って未観測の事象を予測、推定するスキルが「推測統計学」
  • 母集団 (population) から標本 (sample) を無作為に抽出し、その標本によって得られた標本平均や不偏分散などの統計量を使って、母集団の母数(母平均や母分散)を検定し推定する 
  • 推測統計学の基本的な考えは、母集団からランダムに抽出した標本を増やし、無限に試行を繰り返せば、全体の一部である標本から、巨大で未知の母集団を推測できる、ということ 
  • 推測統計学では、分析対象が確率分布すると考える 

・ここでは両統計学で共通して使う基礎知識を解説・演習する

2. 記述統計量

  • 記述統計量(descriptive statistics)とは「ある変数が持つ情報を要約した数値」

代表的な記述統計量

記述統計量 解説
mean() 平均値 mean
median() 中央値 median
sd() 不偏標準偏差 standard deviation
var() 不偏分散 variance
IQR() 四分位範囲 Interquartile range*
min() 最小値 minimum
max() 最小値と最大値 maximum

* 四分位範囲とは、75パーセンタイルと25パーセンタイルの差のこと

  • 例えば、学生 9 人の TOEFL (iBT) の平均点が得られたとする
  • 2 番目の学生のスコアーは欠損値 (NA) とする
x <- c(22, 33, 44, 55, 66, 77, 88, 99, 100)
x
[1]  22  33  44  55  66  77  88  99 100
  • x を代表する値(=代表値)として平均値、中央値、分散、標準偏差、四分位範囲、範囲を求めてみる

2.1 平均値

  • 変数\(x\) の平均\(\bar{x}\) は次の式で求めることができる:
    \[\bar{x} = \frac{\sum_{i=1}^n x_i}{n}\]

  • R を使って平均点を計算する方法① 

  • 最も手間の掛かる方法

(22 + 33 + 44 + 55 + 66 + 77 + 88 + 99 + 100)/9
[1] 64.88889
  • R を使って平均点を計算する方法② 
  • sum( ) を使う
sum(x/9)
[1] 64.88889
  • R を使って平均点を計算する方法③ 
  • mean( ) を使う
mean(x)
[1] 64.88889

2.2 中央値(真ん中の値)

median(x)
[1] 66
  • x を小さい順にソートしてみる
sort(x)
[1]  22  33  44  55  66  77  88  99 100
  • 66 が真ん中にある(=中央値)だとわかる

2.3 分散(ばらつき)

  • 分散 (variance) とは数値データのばらつき具合を表すための指標

  • 分散は「平均値と個々のデータの差の2乗の平均」

  • 平均値から離れた値をとるデータが多い → 分散が大きい

  • 平均点付近の値をとるデータ多い → 分散が小さい

分散

  • 一般的に分散は次の式で求められる 
    \[分散 = \frac{\sum_{i=1}^N (個々のデータ - 平均)^2}{N}\]

  • 次のように表記されることが多い

  • 分散 \(σ^2\)(シグマ)は次のように表記されることが多い 
    \[σ^2 = \frac{\sum_{i=1}^N (x_i - \bar{x})^2}{N}\]

  • x が得られたサンプルデータだとする

分散を計算してみる

x
[1]  22  33  44  55  66  77  88  99 100
  • データ x の平均値を求めて x_mean と名前を付ける 
x_mean <- mean(x)
x_mean
[1] 64.88889
  • 平均からの偏差(個々のデータ - 平均)を求めて x1 と名前を付ける 
x1 <- x - x_mean
x1
[1] -42.888889 -31.888889 -20.888889  -9.888889   1.111111  12.111111  23.111111
[8]  34.111111  35.111111
  • 例えば、[1]の右隣にある数値 (-42.888889) は、データ x の先頭の値 (22) から平均値 (64.88889) を引いた値
22 - 64.88889 # x[1] - mean(x)でも同じ結果が得られる
[1] -42.88889
  • 次に、上で求めた「平均からの偏差」を 2 乗して x2 と名付ける 
x2 <- x1^2
x2
[1] 1839.456790 1016.901235  436.345679   97.790123    1.234568  146.679012
[7]  534.123457 1163.567901 1232.790123
  • 「平均からの偏差」の 2 乗和を求め sum_x2 と名付ける 
sum_x2 <- sum(x2)
sum_x2
[1] 6468.889
  • これで分散を求める式の分子は完成 

  • 分母の数 (N) は 9

  • 従って、x の分散 \(σ^2\) は、 \[σ^2 = \frac{\sum_{i=1}^N (x_i - \bar{x})^2}{N} = \frac{6468.889}{9} = 718.7654\]

  • ここで求めた分散は「標本分散」と呼ばれる

var() を使って分散を求めてみる

var(x)
[1] 808.6111

上で求めた分散 (718.7654) とは異なる値が出た

→ その理由: var() が計算するのは「標本分散 \(σ^2\)」 ではなく「不偏分散 \(S^2\)だから

・標本を使った通常の分析では「不偏分散 \(S^2\)」を使う方が一般的
R で分散を計算する関数 var() では不偏分散 \(S^2\) をデフォルトに設定している

不偏分散と標本分散

「不偏分散」「標本分散」は使い分ける必要がある 

不偏分散・・・「母集団に興味がある場合」に使う散(=標本不偏分散)
標本分散・・・「抽出したサンプルにだけ興味がある場合」に使う

不偏分散 \(S^2\)を使う場合 (R ではデフォルト):

・母集団データの一部だけが手元にあり、入手したデータの背後にある母集団データの散らばりを知りたい場合 

【不偏分散 \(S^2\) を求める式】:var() で計算可能

・仮に \(x\) が母集団から抽出された標本だとしよう 
・母分散は未知なので、標本として得られた統計量を使って未知の母分散を推定する
・母分散を推定するための統計量が不偏分散 \(S^2\)
・不偏分散 \(S^2\)は次の式で求められる 

\[S^2 = \frac{\sum_{i=1}^N (x_i - \bar{x})^2}{N-1}\]

\(\bar{x}\): 標本平均

・Rで計算してみる

sum((x - mean(x))^2) / (length(x) - 1) # var(x) でも同じ結果を得る  
[1] 808.6111
  • var() でも x の不偏分散 \((S^2)\) の値が出力される 
# 不偏分散
var(x)
[1] 808.6111
標本分散 \(σ^2\)を使う場合:

・母集団から抽出された標本(サンプル)が手元にある
・興味の対象が母集団ではなく、標本(サンプル)だけにあるとき
・そのサンプルがどの程度散らばっているかということだけを知りたい時 

【分散 \(σ^2\) を求める式】
・標本分散 \(\sigma^2\)(シグマ)は次の式で求められる 

\[\sigma^2 = \frac{\sum_{i=1}^N (x_i - \bar{x})^2}{N}\]

\(\bar{x}\): 標本平均

R には標本分散 \(\sigma^2\) を求める機能がない
\(\sigma^2\) は次の式を作って計算しなければならない 

# 標本分散
var(x) * (length(x) - 1) / length(x)
[1] 718.7654

標本分散 \(\sigma^2\ \) (718.7654) より、不偏分散 (808.6111) \(S_x^2\) の方が常に大きい

・標本分散 \(\sigma^2\) を求める式では分母が N なのに、不偏分散 \(S^2\) を求める式では分母が N - 1 だから 

分散の計算で2乗 (\(σ^2\)\(S^2\)) の和の平均をとる理由 ・1つの群における各データの数値の平均からの差(=偏差)はぞれが平均値からどれだけ離れているかを表す指標
→ 偏差はプラスとマイナス両方を取り得る
→ 各データが平均値からどれだけ離れているかを表す指標として不適切
偏差を2乗することにより、平均値からの距離の基準を絶対値に換算することで適切な指標に変換できる

2.4 標準偏差(ばらつき)

  • 標準偏差は分散の平方根

\[標準偏差 = \sqrt{分散}\]

  • 分散は、計算する過程で 2 乗されている
    → 本来の単位ではない
    → 数値の意味が変わってしまう
  • 平方根をとることによって単位を揃えた → 標準偏差

\[不偏標準偏差 (S) = \sqrt{不偏分散 (S^2)}\]

  • x の不偏標準偏差 (\(S\)) は次のいずれの式でも表せる
sqrt(var(x))
[1] 28.43609
sd(x)
[1] 28.43609

2.5 四分位範囲

  • データの75パーセンタイル (3rd Qu.) と25パーセンタイル (1st Qu.) の差
IQR(x)
[1] 44

2.6 範囲

max(x, na.rm = TRUE) - min(x)
[1] 78

2.7 記述統計をまとめて表示: summary()

  • 変数 x の統計量のサマリーを表示させる 
summary(x)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  22.00   44.00   66.00   64.89   88.00  100.00 
  • ここでは変数ごとに次の情報が表示されている 
記述統計量 解説
Min: 最小値
1st Qu.: 1st Quantile (25%)
Median: 中央値 (50%)
Mean: 平均値
3rd Qu: 3rd Quantile (75%)
Max: 最大値

3. dplyrを用いた記述統計量の計算

  • dplyrパッケージを含む tidyverse パッケージをロード
library(tidyverse)

データの準備 (hr96-21.csv) hr96-21.csv をクリックしてデータをパソコンにダウンロード  

  • RProject フォルダ内に data という名称のフォルダを作成する
  • ダウンロードした hr96-21.csv を手動でRProject フォルダ内にある data フォルダに入れる
  • 選挙データの読み取る
hr <- read_csv("data/hr96-21.csv",
               na = ".")  
  • hr96_21.csv は1996年に衆院選挙に小選挙区が導入されて以来実施された 9 回の衆議院選挙(1996, 2000, 2003, 2005, 2009, 2012, 2014, 2017, 2021)の結果のデータ

  • 読み取った選挙データを確認

  • dim() 関数を使うと hr は9,660行、22列のデータであることが分かる

dim(hr)
[1] 9660   22
  • df1 には 22 個の変数が入っている
変数名 詳細
year 選挙年 (1996-2017)
pref 都道府県名
ku 小選挙区名
kun 小選挙区
rank 当選順位
wl 選挙の当落: 1 = 小選挙区当選、2 = 復活当選、0 = 落選
nocand 立候補者数
seito 候補者の所属政党
j_name 候補者の氏名(日本語)
name 候補者の氏名(ローマ字)
previous これまでの当選回数(当該総選挙結果は含まない)
gender 立候補者の性別: “male”, “female”
age 立候補者の年齢
exp 立候補者が使った選挙費用(総務省届け出)
status 候補者のステータス: 0 = 非現職、1 現職、2 = 元職
vote 得票数
voteshare 得票率 (%)
eligible 小選挙区の有権者数
turnout 小選挙区の投票率 (%)
seshu_dummy 世襲候補者ダミー: 1 = 世襲、0 = 非世襲(地盤世襲 or 非世襲)
jiban_seshu 地盤の受け継ぎ元の政治家の氏名と関係
nojiban_seshu 世襲元の政治家の氏名と関係

3.1 記述統計を個別に計算する: summarise()

summarise()関数の使い方 summarise(記述統計の関数, 変数名1, 変数名2,...)

  • 例えば、選挙費用 (exp) の平均を計算する場合
hr |> 
  summarise(mean(exp))
# A tibble: 1 × 1
  `mean(exp)`
        <dbl>
1          NA

選挙費用の平均値が計算されない!

→ その理由・・・exp に欠損値があるため
→ na.rm = TRUE(欠損値を取り除く指定)を加えてみる

hr |> 
  summarise(mean(exp, na.rm = TRUE))
# A tibble: 1 × 1
  `mean(exp, na.rm = TRUE)`
                      <dbl>
1                  7551393.
  • summarise() 内には複数の変数名を指定できる
  • 例えば、hrexpage の平均値 (mean()) と標準偏差 (sd()) を計算してみる
hr |> 
  summarise(mean(exp, na.rm = TRUE), # exp の平均値
         sd(exp, na.rm = TRUE), # exp の標準偏差
         mean(age, na.rm = TRUE), # age の平均値
         sd(age, na.rm = TRUE)) # age の標準偏差
# A tibble: 1 × 4
  `mean(exp, na.rm = TRUE)` `sd(exp, na.rm = TRUE)` mean(age, na.rm = …¹ sd(ag…²
                      <dbl>                   <dbl>                <dbl>   <dbl>
1                  7551393.                5482684.                 51.2    11.1
# … with abbreviated variable names ¹​`mean(age, na.rm = TRUE)`,
#   ²​`sd(age, na.rm = TRUE)`
  • 出力結果はデータフレーム(tibble)形式で表示される
  • 変数名が長く、非常に読みにくい
  • rename() 関数を使って変数名を修正できる
hr |> 
  summarise(Mean_exp = mean(exp, na.rm = TRUE),
            SD_exp   = sd(exp, na.rm = TRUE),
            Mean_age = mean(age, na.rm = TRUE), 
            SD_age   = sd(age, na.rm = TRUE)) 
# A tibble: 1 × 4
  Mean_exp   SD_exp Mean_age SD_age
     <dbl>    <dbl>    <dbl>  <dbl>
1 7551393. 5482684.     51.2   11.1
  • かなりみやすくなった

3.2 グルーピング: group_by()

1 グループ

  • 特定の変数の記述統計量を計算する場合は mean()sd() などの関数のみを使った方が効率的
  • グループごとに記述統計量を計算する場合は、dplyr パッケージが大変便利
  • 例えば、dplyr を使わずに総選挙ごとの選挙費用 (exp) の平均値を計算してみる
  • 1996年総選挙の値が「1996」である場合の選挙費用 (exp) の平均値を計算する場合は以下のように書く必要がある
    注意exp に欠損値があるため na.rm = TRUE(欠損値を取り除く指定)を加えている
mean(hr$exp[hr$year == 1996], na.rm = TRUE)
[1] 9136316
  • これを 1996年から2021年までの 8 つの総選挙ごとに計算しなければならないので、次のように入力する必要がある
mean(hr$exp[hr$year == 1996], na.rm = TRUE)
mean(hr$exp[hr$year == 2000], na.rm = TRUE)
mean(hr$exp[hr$year == 2003], na.rm = TRUE)
mean(hr$exp[hr$year == 2005], na.rm = TRUE)
mean(hr$exp[hr$year == 2009], na.rm = TRUE)
mean(hr$exp[hr$year == 2012], na.rm = TRUE)
mean(hr$exp[hr$year == 2014], na.rm = TRUE)
mean(hr$exp[hr$year == 2017], na.rm = TRUE)
mean(hr$exp[hr$year == 2019], na.rm = TRUE)
mean(hr$exp[hr$year == 2021], na.rm = TRUE)
  • しかし、dplyr パッケージの group_by() 関数を使うと驚くほどコマンドが簡素化できる  

group_by()関数の使い方 group_by(グループ化する変数名) |>
  summarise(...)

  • hryear ごとにデータをグループ化し、exp の平均値を計算する場合
  • summarise() の前 に group_by(year) を使ってパイプをつなぎ
    → year ごとに exp の平均値を計算する
hr |> 
  group_by(year) |> 
  summarise(Mean_exp = mean(exp, na.rm = TRUE))
# A tibble: 9 × 2
   year Mean_exp
  <dbl>    <dbl>
1  1996 9136316.
2  2000 8388889.
3  2003 7935408.
4  2005 8142244.
5  2009 6118181.
6  2012 5769988.
7  2014 7440127.
8  2017 9298783.
9  2021     NaN 

複数でのグループ化

  • group_by() 関数は 2 つ以上の変数でのグルーピングも可能
  • 政党ごとにどれだけ選挙費用を使っているかを時系列で調べたいとする
  • hryearseito でデータをグループ化し、exp の平均値を計算してみる
hr |> 
  group_by(year, seito) |> 
  summarise(Mean_exp = mean(exp, na.rm = TRUE))
# A tibble: 113 × 3
# Groups:   year [9]
    year seito                   Mean_exp
   <dbl> <chr>                      <dbl>
 1  1996 さわやか神戸・市民の会      NaN 
 2  1996 共産                    3158354.
 3  1996 国民党                      NaN 
 4  1996 市民新党にいがた        3044160 
 5  1996 政事公団太平会             5540 
 6  1996 文化フォーラム              NaN 
 7  1996 新党さきがけ           13030901 
 8  1996 新社会                  4545681 
 9  1996 新進                   12395369.
10  1996 日本新進                1898969 
# … with 103 more rows
  • これだと政党の数が多すぎて煩雑なので、政党を自民党と民主党の 2 つだけに絞って計算してみる
unique(hr$seito)
 [1] "新進"                   "自民"                   "民主"                  
 [4] "共産"                   "文化フォーラム"         "国民党"                
 [7] "無所"                   "自由連合"               "政事公団太平会"        
[10] "新社会"                 "社民"                   "新党さきがけ"          
[13] "沖縄社会大衆党"         "市民新党にいがた"       "緑の党"                
[16] "さわやか神戸・市民の会" "民主改革連合"           "青年自由"              
[19] "日本新進"               "公明"                   "諸派"                  
[22] "保守"                   "無所属の会"             "自由"                  
[25] "改革クラブ"             "保守新"                 "ニューディールの会"    
[28] "新党尊命"               "世界経済共同体党"       "新党日本"              
[31] "国民新党"               "新党大地"               "幸福"                  
[34] "みんな"                 "改革"                   "日本未来"              
[37] "日本維新の会"           "当たり前"               "政治団体代表"          
[40] "安楽死党"               "アイヌ民族党"           "次世"                  
[43] "維新"                   "生活"                   "立憲"                  
[46] "希望"                   "緒派"                   ""                      
[49] "N党"                   "国民"                   "れい"                  
# `ggplot` で文字バケしない設定(マックユーザーのみ)  
theme_set(theme_classic(base_size = 10,
                        base_family = "HiraginoSans-W3"))
hr |>  
  group_by(year, seito) |> 
  summarise(Mean_exp = mean(exp, na.rm = TRUE)) |> 
  filter(seito == "自民" | seito == "民主") 
# A tibble: 16 × 3
# Groups:   year [9]
    year seito  Mean_exp
   <dbl> <chr>     <dbl>
 1  1996 民主   9961458.
 2  1996 自民  14460093.
 3  2000 民主  10207109.
 4  2000 自民  14251423.
 5  2003 民主   9772028.
 6  2003 自民  12821990.
 7  2005 民主   9574473.
 8  2005 自民  12710075.
 9  2009 民主   7802585.
10  2009 自民  11374974.
11  2012 民主   7728045.
12  2012 自民   9335490.
13  2014 民主   9757272 
14  2014 自民  11450459.
15  2017 自民  12338476.
16  2021 自民       NaN 
  • ggplot() 関数を使って自民党と民主党それぞれの候補者の選挙費用の平均値を可視化してみる
  • </