Chapter 8 データ前処理
【Section 8.7に関連動画を紹介しています。】
データをインポートしたら、いざ分析だ!…と分析してみたくなります。 しかし、収集したデータはそのまま分析に進むことはできず、分析のために「前処理」する必要があります。 「データ分析は前処理が8割」とも言われます。 前処理の方法を学んでいきましょう。
データ前処理にはdplyr
(読み:ディープライアール)というパッケージの関数を主に用います。
dplyr
はtidyverse
の一部なので、tidyverse
がインストールされていればOKです。
8.1 パイプ(%>%)による処理
最近はパイプ%>%
を用いてデータの受け渡しを行うのが主流となっています。
パイプはmagrittr
パッケージの機能ですが、tidyverse
と同時にインストールされています。
まずは例を見てみましょう。
%>% head() saving
## sav inc size educ age black cons
## 1 30 1920 4 2 40 1 1890
## 2 874 12403 4 9 33 0 11529
## 3 370 6396 2 17 31 0 6026
## 4 1200 7005 3 9 50 0 5805
## 5 275 6990 4 12 28 0 6715
## 6 1400 6500 4 13 33 0 5100
この結果は、前のChapterで見たhead(saving)
と同じ結果です。
パイプを用いると、パイプの前のオブジェクトをパイプの後の関数の引数としてくれます。
パイプを用いた書き方は以下のとおりです。
- 使用するオブジェクトを示す:
saving
- パイプでつなぐ:
%>%
- 使用する関数を書く:
head()
別の例を見てみましょう。
$sav %>% mean() saving
## [1] 1582.51
まずデータフレームsaving
内の変数sav
(貯蓄)を示すオブジェクトsaving$sav
を書きます。
これを平均を求める関数mean()
にパイプ%>%
でつなぎます。
すると、貯蓄の平均を求めることができます。
ここまででは何が便利なのかわからないかもしれませんが、パイプを用いたほうがコードをわかりやすく書くことができます。
★練習問題
- パイプを使って100の平方根を求めてください。
- パイプを使って
saving
の変数inc
の中央値を求めてください。
8.2 変数の作成(及び置換)
分析の際には、収集したデータを分析しやすいように作成・置換することはよくあります。
- 新しい変数を作成したい
- 質問紙に逆転項目を設けていたので、変数を逆にしたい
- 変数を標準化したい
- 数値で入力された変数をカテゴリ変数として扱いたい
- 連続変数をカテゴリ変数に変換したい
変数を追加・置換するdplyr
の関数がmutate()
です。
8.2.1 変数の新規作成
mutate()
を用いて、貯蓄sav
を収入inc
で割った新しい変数「貯蓄率」saving_rate
を作ってみましょう。
<-
saving_with_rate %>%
saving mutate(saving_rate = sav / inc)
head(saving_with_rate)
## sav inc size educ age black cons saving_rate
## 1 30 1920 4 2 40 1 1890 0.01562500
## 2 874 12403 4 9 33 0 11529 0.07046682
## 3 370 6396 2 17 31 0 6026 0.05784866
## 4 1200 7005 3 9 50 0 5805 0.17130621
## 5 275 6990 4 12 28 0 6715 0.03934192
## 6 1400 6500 4 13 33 0 5100 0.21538462
1行目は2行目以降の結果を新たなデータフレームsaving_with_rate
に代入するコードです。
2行目はデータフレームの指定とパイプです。saving
をmutate()
に入れるコードです。
3行目でmutate
を使っています。割り算/
を使って、新しい変数saving_rate
を作成しました。
head(saving_with_rate)
でどのようなデータフレームになったか、先頭6行を確認しています。
なお、1行目をsaving
とすると、saving
が上書きされます。
★練習問題
saving
に年齢age
を二乗した値age_squared
を加えたデータフレームを作成してください。saving
に収入inc
を円換算した値inc_yen
を加えたデータフレームを作成してください。- 当時の為替レートは1ドル=140円程度でした。
8.2.2 逆転項目の処理
mutate
を利用して、「逆転項目」の前処理をしてみましょう。
逆転項目とは、質問紙では1, 2, 3, 4, 5として聞いた数値を、データでは5, 4, 3, 2, 1として扱うものです(5件法の場合)。
以下の操作をイメージしましょう。
- 全体にマイナスをかける→(1, 2, 3, 4, 5)が(-1, -2, -3, -4, -5)になる
- 全体に6を足す→(-1, -2, -3, -4, -5)が(5, 4, 3, 2, 1)になる
つまり、元の変数にマイナスをかけ、6を足せば逆転項目が作成できます。
saving
には逆転項目がないので、架空の数値を作成して確認してみましょう。
<- data.frame(Q1 = c(3, 2, 4, 1, 5)) #逆転項目Q1が入ったデータフレームを作成
data
<-
data_gyakuten %>%
data mutate(Q1_gyakuten = - Q1 + 6)
data_gyakuten
## Q1 Q1_gyakuten
## 1 3 3
## 2 2 4
## 3 4 2
## 4 1 5
## 5 5 1
★練習問題
- 7件法(1〜7)で収集した架空のデータフレームを作成し、逆転項目として処理してみてください。
8.2.3 変数の標準化
変数を平均0、標準偏差1の変数に変換する標準化は、変数の解釈を容易にしたり、以降の分析をしやすくするために必要です。
標準化を行う関数はscale()
です。mutate()
と組み合わせて、教育年数educ
を標準化した変数educ_standardized
を作ってみましょう。
<-
saving_standardized_educ %>%
saving mutate(educ_standardized = scale(educ))
head(saving_standardized_educ)
## sav inc size educ age black cons educ_standardized
## 1 30 1920 4 2 40 1 1890 -2.7886549
## 2 874 12403 4 9 33 0 11529 -0.7510156
## 3 370 6396 2 17 31 0 6026 1.5777150
## 4 1200 7005 3 9 50 0 5805 -0.7510156
## 5 275 6990 4 12 28 0 6715 0.1222584
## 6 1400 6500 4 13 33 0 5100 0.4133497
★練習問題
- 年収
inc
を標準化した値inc_standardized
を加えたデータフレームを作成してください。
8.3 カテゴリ変数の処理
8.3.1 変数の型
Rで扱う変数には「型」と呼ばれる区別があります。
型の違いによって、今後の分析方法も変わってきます。
型を確認する方法として、オブジェクトの構造を確認する関数str()
を使ってみましょう。
str(saving)
## 'data.frame': 100 obs. of 7 variables:
## $ sav : int 30 874 370 1200 275 1400 3159 1766 3984 1017 ...
## $ inc : int 1920 12403 6396 7005 6990 6500 26007 15363 14999 9185 ...
## $ size : int 4 4 2 3 4 4 5 5 5 5 ...
## $ educ : int 2 9 17 9 12 13 17 16 9 16 ...
## $ age : int 40 33 31 50 28 33 36 44 48 31 ...
## $ black: int 1 0 0 0 0 0 0 0 1 0 ...
## $ cons : int 1890 11529 6026 5805 6715 5100 22848 13597 11015 8168 ...
## - attr(*, "time.stamp")= chr "25 Jun 2011 23:03"
$の右が変数名、int
と書かれているのが型です。
ここではすべてint
となっていますが、これは整数(integer)を表します。
以下の型はすべて数値として扱われます。
- int: integer, 整数
- dbl: double, 実数
- num: numeric, 数値
8.3.2 カテゴリ変数への変換
カテゴリ変数を表す型はfct (factor)です。saving
にはカテゴリ変数がないので、カテゴリ変数を作成してみましょう。
型を変換する関数がas_xxx()
です。xxxは変換したい型の名前を入れてください。
ここでは、カテゴリ変数に変換したいので、as_factor()
を用います。
今はinteger型となっているblack
をカテゴリ変数にしてみましょう。
<-
saving_with_factor %>%
saving mutate(black_factor = as_factor(black))
str(saving_with_factor)
## 'data.frame': 100 obs. of 8 variables:
## $ sav : int 30 874 370 1200 275 1400 3159 1766 3984 1017 ...
## $ inc : int 1920 12403 6396 7005 6990 6500 26007 15363 14999 9185 ...
## $ size : int 4 4 2 3 4 4 5 5 5 5 ...
## $ educ : int 2 9 17 9 12 13 17 16 9 16 ...
## $ age : int 40 33 31 50 28 33 36 44 48 31 ...
## $ black : int 1 0 0 0 0 0 0 0 1 0 ...
## $ cons : int 1890 11529 6026 5805 6715 5100 22848 13597 11015 8168 ...
## $ black_factor: Factor w/ 2 levels "0","1": 2 1 1 1 1 1 1 1 2 1 ...
## - attr(*, "time.stamp")= chr "25 Jun 2011 23:03"
ここでは、mutate
を使って、新たな変数black_factor
を作成してみました。
str()
を使って、型がFactorになったことが確認できます。
カテゴリ変数として扱いたい変数はすべてas_factor
を使ってカテゴリ変数にしておきましょう。
また、文字列型(chr, character)の変数はこのままでは分析に使用できないので、必ずas_factor
を実行しておきましょう。
★練習問題
- 家族人数
size
をカテゴリ変数に変換したデータフレームを作成してください。
8.3.3 ダミー変数の作成
ある変数から、別のダミー変数を作成したいことはよくあります。
ここでは、教育年数のデータを12年を基準に「高卒以上」「高卒未満」の2つに区分してみましょう。
2つの場合分けの際には、if_else
関数を使うと便利です。
if_else()
はif_else(条件, 条件が成りたつ場合の値, 条件が成り立たない場合の値)
と書いて使用します。
table(saving$educ) #教育年数の度数分布
##
## 2 3 4 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## 1 1 1 1 4 10 11 9 4 32 2 4 1 9 6 2 1 1
<-
saving_with_hsdummy %>%
saving mutate(highschool = if_else(educ >= 12, 1, 0))
head(saving_with_hsdummy)
## sav inc size educ age black cons highschool
## 1 30 1920 4 2 40 1 1890 0
## 2 874 12403 4 9 33 0 11529 0
## 3 370 6396 2 17 31 0 6026 1
## 4 1200 7005 3 9 50 0 5805 0
## 5 275 6990 4 12 28 0 6715 1
## 6 1400 6500 4 13 33 0 5100 1
table(saving_with_hsdummy$highschool) #作成したダミー変数の度数分布
##
## 0 1
## 42 58
highschool
という教育年数が12年以上であれば1、教育年数が12年未満であれば0を示すダミー変数を作成することができました。
なお、ここで作成した変数は連続変数として扱われているので、必要に応じてas_factor()
も行っておきましょう。
<-
saving_with_hsdummy %>%
saving mutate(highschool = if_else(educ >= 12, 1, 0),
highschool = as_factor(highschool)) #highschoolをfactor型として上書き
head(saving_with_hsdummy)
## sav inc size educ age black cons highschool
## 1 30 1920 4 2 40 1 1890 0
## 2 874 12403 4 9 33 0 11529 0
## 3 370 6396 2 17 31 0 6026 1
## 4 1200 7005 3 9 50 0 5805 0
## 5 275 6990 4 12 28 0 6715 1
## 6 1400 6500 4 13 33 0 5100 1
★練習問題
- 「年齢が40代以上」を表すダミー変数
over40
を加えたデータフレームを作成してください。
8.3.4 カテゴリ変数の作成
2つのカテゴリにしたい場合は上記のif_else
が良いですが、3つ以上にしたい場合はcase_when
が便利です。
例えば年齢age
を年代別のカテゴリ変数にしてみましょう。
case_when
はcase_when(条件A ~ 条件が成り立つ場合の値, 条件B ~ 条件が成り立つ場合の値...
と書いていきます。
summary(saving$age) #年齢の記述統計の確認
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 26.00 33.00 38.50 38.77 44.00 54.00
<-
saving_with_age_category %>%
saving mutate(age_category = case_when(age < 30 ~ "20s",
>= 30 & age < 40 ~ "30s",
age >= 40 & age < 50 ~ "40s",
age >= 50 ~ "50s"
age
)
)
head(saving_with_age_category)
## sav inc size educ age black cons age_category
## 1 30 1920 4 2 40 1 1890 40s
## 2 874 12403 4 9 33 0 11529 30s
## 3 370 6396 2 17 31 0 6026 30s
## 4 1200 7005 3 9 50 0 5805 50s
## 5 275 6990 4 12 28 0 6715 20s
## 6 1400 6500 4 13 33 0 5100 30s
少し長くなってしまいましたが、年齢の条件別に年代別の文字列を割り当てました。
ここで生成した変数はchr(character)型になっているので、分析に使う場合はas_factor
を行っておきましょう。
★練習問題
- 年収6000ドル未満を“poor”、年収6000ドル以上12000ドル未満を“middle”、 年収12000ドル以上を“rich”、とするカテゴリ変数
inc_category
を追加したデータフレームを作成しなさい。
8.4 変数の選択
インポートしたデータの中に不要な変数が含まれていたり、前処理の結果不要になった変数が出てくることはよくあります。
dplyr
の関数select()
を用いると、データフレームの変数を選択したり、削除したりすることができます。
まずはsaving
から収入inc
と年齢age
を取り出してみましょう。
<-
saving_selected %>%
saving select(inc, age)
head(saving_selected)
## inc age
## 1 1920 40
## 2 12403 33
## 3 6396 31
## 4 7005 50
## 5 6990 28
## 6 6500 33
2つの変数のみのデータフレームになりました。
ハイフン-
を使うと、該当する変数を削除し、残りの変数はそのままとすることができます。
saving
から消費cons
を取り除いてみましょう。
<-
saving_deleted %>%
saving select(-cons)
head(saving_deleted)
## sav inc size educ age black
## 1 30 1920 4 2 40 1
## 2 874 12403 4 9 33 0
## 3 370 6396 2 17 31 0
## 4 1200 7005 3 9 50 0
## 5 275 6990 4 12 28 0
## 6 1400 6500 4 13 33 0
★練習問題
- 貯蓄
sav
、家族の人数size
、黒人ダミーblack
の3変数のデータフレームを作成してください。 - 教育年数
educ
、年齢age
を取り除いたデータを作成してください。
8.5 変数の並び替え
データを確認する際に、ある変数をもとに並べ替えたい場合があります。
データを並べ替えるdplyr
の関数がarrange()
です。
ここでは、saving
を収入inc
で並び替えてみましょう。
<-
saving_arranged %>%
saving arrange(inc)
head(saving_arranged)
## sav inc size educ age black cons
## 1 0 750 2 4 49 0 750
## 2 30 1920 4 2 40 1 1890
## 3 50 2340 2 6 46 1 2290
## 4 -112 2936 7 10 39 0 3048
## 5 2575 3941 4 9 34 0 1366
## 6 2483 4091 6 8 44 0 1608
値が小さいものが上、値が大きいものが下となる昇順で並び替えられます。
逆に降順にしたい場合は、desc()
を利用します。
<-
saving_arranged_desc %>%
saving arrange(desc(inc))
head(saving_arranged_desc)
## sav inc size educ age black cons
## 1 1800 32080 2 16 54 0 30280
## 2 10668 30996 4 12 41 0 20328
## 3 4115 30610 4 16 44 0 26495
## 4 3159 26007 5 17 36 0 22848
## 5 -2749 24226 5 17 44 0 26975
## 6 5082 19362 3 11 48 0 14280
8.6 すべての作業をパイプでつなげる
これまで行ってきた一連の作業は、すべてパイプ%>%
でつなげることができます。
パイプでつなげることで作業の流れがわかりやすくなり、不要なオブジェクトを生成する必要もなくなります。
ここでは、以下の作業をまとめて行ってみましょう。
- 貯蓄率
saving_rate
の作成 - 家族人数
size
の削除 - 収入
inc
で並び替え(降順)
<-
saving_handled %>%
saving mutate(saving_rate = sav / inc) %>%
select(-size) %>%
arrange(desc(inc))
head(saving_handled)
## sav inc educ age black cons saving_rate
## 1 1800 32080 16 54 0 30280 0.05610973
## 2 10668 30996 12 41 0 20328 0.34417344
## 3 4115 30610 16 44 0 26495 0.13443319
## 4 3159 26007 17 36 0 22848 0.12146730
## 5 -2749 24226 17 44 0 26975 -0.11347313
## 6 5082 19362 11 48 0 14280 0.26247289
コードが長くなるため、適宜#
を使ってコメントを加えておくと良いでしょう。
saving_handled%>%
saving mutate(saving_rate = sav / inc) %>% #貯蓄率の作成
select(-size) %>% #家族人数の削除
arrange(desc(inc)) #収入で並び替え(高いものが上)