第6章 欠損値の扱い
欠損値 (missing value) とは観測ができなかった、あるいはその時点において観察対象が存在していなかった、などの理由から変数が欠損していることを示しています。
Rでは主にNA
として表示されます。
ここでは、Rにおける欠損値の扱い方について説明します。
- ここでは欠損値の対処法(例、多重代入法)は触れません。
6.1 欠損値を読み込む
Rでは読み込むデータにおいて空欄である場合に欠損値として認識し、データセット内ではNA
と表示されます。
例えば、dyplyr
に含まれているstarwars
というデータセットを見てみると、身長や重量、誕生年にNA
がいくつかあるのが分かります。
## name height mass hair_color
## Length:87 Min. : 66.0 Min. : 15.00 Length:87
## Class :character 1st Qu.:167.0 1st Qu.: 55.60 Class :character
## Mode :character Median :180.0 Median : 79.00 Mode :character
## Mean :174.4 Mean : 97.31
## 3rd Qu.:191.0 3rd Qu.: 84.50
## Max. :264.0 Max. :1358.00
## NA's :6 NA's :28
## skin_color eye_color birth_year sex
## Length:87 Length:87 Min. : 8.00 Length:87
## Class :character Class :character 1st Qu.: 35.00 Class :character
## Mode :character Mode :character Median : 52.00 Mode :character
## Mean : 87.57
## 3rd Qu.: 72.00
## Max. :896.00
## NA's :44
## gender homeworld
## Length:87 Length:87
## Class :character Class :character
## Mode :character Mode :character
##
##
##
##
問題は、もとのデータセットにおいて欠損値が空欄になっているとは限らないという点です。 例えば、Polity IVというデータセットを開いてみます。
polity <- read_excel("data/p4v2017.xls") %>%
select(ccode, country, year, democ, autoc)
summary(polity)
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. :-88.00000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.00000
## Median :366.0 Mode :character Median :1959 Median : 1.00000
## Mean :404.2 Mean :1940 Mean : -0.08928
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.00000
## Max. :950.0 Max. :2017 Max. : 10.00000
## autoc
## Min. :-88.0000
## 1st Qu.: 0.0000
## Median : 4.0000
## Mean : 0.3837
## 3rd Qu.: 7.0000
## Max. : 10.0000
一見すると欠損値はないように見えますが、よく見るとdemoc
とautoc
の最小値が-88
となっています。
コードブックをよく見ると分かるのですが、実は-66
、-77
、-88
はそれぞれ被介入、無政府、移行期を意味しています。
それらの違いを無視することは問題があるものの、これらを欠損値に置き換えることがしばしばあります。
polity$democ[polity$democ %in% c(-66, -77, -88)] <- NA
polity$autoc[polity$autoc %in% c(-66, -77, -88)] <- NA
summary(polity)
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.000
## Median :366.0 Mode :character Median :1959 Median : 1.000
## Mean :404.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## NA's :776
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
## NA's :776
- 無事、欠損値が正しく認識されて、最小値が
0
になりました。
なお、欠損値が-
や.
のような文字列になっている場合、欠損値に入れ替えた後にas.numeric()
などで数値データに変換するのを忘れないようにしましょう。
tidyverse
のdplyr
で欠損値を扱うときの方法を説明します。
まず。元データにおける欠損値が空欄ではない場合は、データを読み込む際にオプションna
で指定します。
polity <- read_excel("data/p4v2017.xls", na = c("-66", "-77", "-88")) %>%
select(ccode, country, year, democ, autoc)
summary(polity)
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.000
## Median :366.0 Mode :character Median :1959 Median : 1.000
## Mean :404.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## NA's :776
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
## NA's :776
- 文字列として指定する点に注意してください。
あるいは、面倒くさいですがna_if()
という関数を使うことも可能です。
polity <- read_excel("data/p4v2017.xls", na = c("-66", "-77", "-88")) %>%
select(ccode, country, year, democ, autoc) %>%
mutate(democ = na_if(democ, -66),
democ = na_if(democ, -77),
democ = na_if(democ, -88),
autoc = na_if(autoc, -66),
autoc = na_if(autoc, -77),
autoc = na_if(autoc, -88))
summary(polity)
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.000
## Median :366.0 Mode :character Median :1959 Median : 1.000
## Mean :404.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## NA's :776
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
## NA's :776
6.2 欠損値を含む観察を除外する
後述するように基本的には欠損値がデータセットに含まれていても問題ないのですが、しばしば欠損値を含む観察を取り除く必要があります。
特定のベクトルのどの要素が欠損しているかを判定する関数はis.na()
です。
これは名前の通り、欠損している場合にTRUE
が返ってくるので、次のようにすることでdemoc
とautoc
が欠損しているサンプルを除外できます。
## ccode country year democ
## Min. : 2.0 Length:16619 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1892 1st Qu.: 0.000
## Median :365.0 Mode :character Median :1959 Median : 1.000
## Mean :403.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
同様のことは次のようにもできます。
## ccode country year democ
## Min. : 2.0 Length:16619 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1892 1st Qu.: 0.000
## Median :365.0 Mode :character Median :1959 Median : 1.000
## Mean :403.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
tidyverse
で欠損値を除く場合はdrop_na()
を使います。
## ccode country year democ
## Min. : 2.0 Length:16619 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1892 1st Qu.: 0.000
## Median :365.0 Mode :character Median :1959 Median : 1.000
## Mean :403.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
drop_na()
の中で変数を指定することで、その変数が欠損している観察だけを除外することもできます。
## ccode country year democ
## Min. : 2.0 Length:16619 Min. :1800 Min. : 0.000
## 1st Qu.:200.0 Class :character 1st Qu.:1892 1st Qu.: 0.000
## Median :365.0 Mode :character Median :1959 Median : 1.000
## Mean :403.2 Mean :1940 Mean : 3.564
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 4.059
## 3rd Qu.: 7.000
## Max. :10.000
6.3 欠損値を置き換える
is.na()
を使うと欠損値を他の数値に書き換えることも可能です。
例えば、欠損値を全て-1
に置き換えるには次のようにします。
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. :-1.000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.000
## Median :366.0 Mode :character Median :1959 Median : 1.000
## Mean :404.2 Mean :1940 Mean : 3.361
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. :-1.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 3.834
## 3rd Qu.: 7.000
## Max. :10.000
tidyverse
で欠損値を他の値に置き換えるときはreplace_na()
を使います。
## ccode country year democ
## Min. : 2.0 Length:17395 Min. :1800 Min. :-1.000
## 1st Qu.:200.0 Class :character 1st Qu.:1894 1st Qu.: 0.000
## Median :366.0 Mode :character Median :1959 Median : 1.000
## Mean :404.2 Mean :1940 Mean : 3.361
## 3rd Qu.:630.0 3rd Qu.:1991 3rd Qu.: 7.000
## Max. :950.0 Max. :2017 Max. :10.000
## autoc
## Min. :-1.000
## 1st Qu.: 0.000
## Median : 4.000
## Mean : 3.834
## 3rd Qu.: 7.000
## Max. :10.000
- 複数の変数を一括で変更する場合は
list()
で選択します。
6.4 欠損値がある場合の分析*
基本的に、欠損値がある場合でも分析をする上で問題はありません。
polity <- read_excel("data/p4v2017.xls") %>%
select(ccode, country, year, democ, autoc)
polity$democ[polity$democ %in% c(-66, -77, -88)] <- NA
polity$autoc[polity$autoc %in% c(-66, -77, -88)] <- NA
6.4.1 一変数の記述統計
例えば、平均値などの記述統計を求める際にはna.rm = TRUE
というオプションをつけます。
## [1] NA
## [1] 3.564174
6.4.2 二変数の記述統計
相関係数や共分散など二変数以上の場合は若干ややこしくなります。
use
オプションで以下の対処法のうち一つを決定します。
everything
:欠損値を含む場合はNA
を返す(デフォぱルト)。all.obs
:欠損値を含む場合はエラーとなる。complete.obs
:全ての変数が欠損していないものだけを使って計算する。pairwise.complete.obs
:二変数が欠損していないサンプルを使って計算する。
いまいちよくわからないのでデモデータを作って確認してみます。
iris
の上から10のサンプルで品種以外のデータを使います。
6.4.2.1 everythingの場合
欠損値を含まない変数Petal.Length
とPetal.WIdth
のみ計算されています。
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length 1 NA NA NA
## Sepal.Width NA 1 NA NA
## Petal.Length NA NA 1.0000000 0.5216405
## Petal.Width NA NA 0.5216405 1.0000000
6.4.2.2 all.obsの場合
欠損値が含まれているのでエラーが起こります。
## Error in cor(demo, use = "all.obs"): missing observations in cov/cor
6.4.2.3 complete.obsの場合
これはどの変数も欠損していないサンプル(つまり、4番目から10番目のサンプル)の相関係数になります。
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length 1.0000000 0.8545604 0.7624091 0.4247114
## Sepal.Width 0.8545604 1.0000000 0.5684454 0.7269985
## Petal.Length 0.7624091 0.5684454 1.0000000 0.5385368
## Petal.Width 0.4247114 0.7269985 0.5385368 1.0000000
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length 1.0000000 0.8545604 0.7624091 0.4247114
## Sepal.Width 0.8545604 1.0000000 0.5684454 0.7269985
## Petal.Length 0.7624091 0.5684454 1.0000000 0.5385368
## Petal.Width 0.4247114 0.7269985 0.5385368 1.0000000
6.4.2.4 pairwise.completeの場合
先ほどと一致しているところと一致していないところがあります。
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Sepal.Length 1.0000000 0.8545604 0.6853616 0.4225771
## Sepal.Width 0.8545604 1.0000000 0.4845437 0.6915641
## Petal.Length 0.6853616 0.4845437 1.0000000 0.5216405
## Petal.Width 0.4225771 0.6915641 0.5216405 1.0000000
例えば、Sepal.Length
とSepal.Width
の場合、どちらも欠損していないのは4番目から10番目のサンプルになります。
なので、complete.obs
のときと同じ結果になります。
## [1] 0.8545604
しかし、Petal.Length
とPetal.Width
の場合、欠損しているサンプルはないので、1番目から10番目のサンプル全てを使った値になります。
## [1] 0.5216405
everything
のときと同じであることも分かります。
6.4.3 回帰分析
回帰分析の際には欠損値を含むサンプルを除外した上で計算します。
##
## Call:
## lm(formula = democ ~ autoc, data = polity)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.5316 -1.5316 0.2009 2.1118 2.5576
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 7.442414 0.023232 320.4 <2e-16 ***
## autoc -0.955418 0.004321 -221.1 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.964 on 16617 degrees of freedom
## (776 observations deleted due to missingness)
## Multiple R-squared: 0.7463, Adjusted R-squared: 0.7463
## F-statistic: 4.888e+04 on 1 and 16617 DF, p-value: < 2.2e-16
776 observations deleted due to missingness
と表示されています。