第5章 データの結合
観察データを分析する際、大抵の場合は複数のデータを集めて、結合した上で分析をする必要があります。
結合の方法には
- 行方向の結合:同じ変数を持っているデータ同士を結合させて観察数を増やす。
- 列方向の結合:同じ種類の観察を持っているデータ同士を結合して変数の数を増やす。
の2種類があります。
5.1 行方向の結合
行方向にデータを結合する必要がある場面としてよくあるのはデータが年や地域ごとに分割されているときです。 例えば、(なぜか)一人あたりGDPのデータが日本と中国で別々のデータになっているとします。
## Parsed with column specification:
## cols(
## name = col_character(),
## year = col_double(),
## gdp_pc = col_double()
## )
## Parsed with column specification:
## cols(
## name = col_character(),
## year = col_double(),
## gdp_pc = col_double()
## )
これを結合するにはrbind()
(row方向の結合)を使いますが、それぞれ同じ変数名を持っている必要があります。
## [1] "Japan" "China"
無事、日本と中国が一つのデータに含まれています。
tidyverse
で行方向の結合の場合、bind_rows()
という関数を使います。
## [1] "Japan" "China"
5.2 列方向の結合
変数を増やすためにデータセットを都合するには列方向に結合する必要があります。 例えば、一人あたりGDPのデータにGDP成長率のデータを結合するとします。
gdp_pc <- read_csv("data/wb_gdp_pc.csv", skip = 4) %>%
select(-"Country Code", -"Indicator Name", -"Indicator Code", -X64)%>%
rename(name = "Country Name") %>%
gather(key = year, value = gdp_pc, -name) %>%
mutate(year = as.numeric(year))
## Warning: Missing column names filled in: 'X64' [64]
## Parsed with column specification:
## cols(
## .default = col_double(),
## `Country Name` = col_character(),
## `Country Code` = col_character(),
## `Indicator Name` = col_character(),
## `Indicator Code` = col_character(),
## `2018` = col_logical(),
## X64 = col_logical()
## )
## See spec(...) for full column specifications.
gdp_gr <- read_csv("data/wb_gdp_growth.csv", skip = 4) %>%
select(-"Country Code", -"Indicator Name", -"Indicator Code", -X64)%>%
rename(name = "Country Name") %>%
gather(key = year, value = gdp_gr, -name) %>%
mutate(year = as.numeric(year))
## Warning: Missing column names filled in: 'X64' [64]
## Parsed with column specification:
## cols(
## .default = col_double(),
## `Country Name` = col_character(),
## `Country Code` = col_character(),
## `Indicator Name` = col_character(),
## `Indicator Code` = col_character(),
## `1960` = col_logical(),
## `2018` = col_logical(),
## X64 = col_logical()
## )
## See spec(...) for full column specifications.
- [ロング・ワイド変換]で紹介するようにワイド形式からロング形式に変換しています。
つまり、モチベーションとしてはこの2つのデータセットを結合して、各国の各年の一人あたりGDPとGDP成長率のデータセットを作成したいとします。
merge()
を使うことでそれが可能になりますが、by
によって結合するデータに共通するそれぞれの観察を特定する変数を指定します。
この場合、各観察は各国の各年なので、name
とyear
を指定します。
tidyverse
で列方向の結合の場合、以下の4つの関数のうちの一つを選びます。
ここでは、x
とy
というデータセットを結合するとします。
left_join(x, y)
:x
にマッチする観察のみを残す。right_join(x, y)
:y
にマッチする観察のみを残す。inner_join(x, y)
:両者に共通する観察のみを残す。full_join(x, y)
:どちらかに含まれる観察を全て残す。
例えば、次のようなX
とY
というデータセットがあり、同じid
のサンプル同士で結合するとします。
X <- tibble(id = c(1,2,3), x = c("x1", "x2", "x3"))
Y <- tibble(id = c(1,2,4), y = c("y1", "y2", "y4"))
X
left_join()
の場合はX
にあるデータだけ残ります。
right_join()
の場合ははY
にあるデータだけ残ります。
inner_join()
の場合は共通して存在するサンプルに、full_join()
の場合は少なくともどちらかに存在するサンプルになるので、後者が一番保守的な結合になります。
- なお、
by
で指定しなくても自動で結合してくれますが、一般的にはby
で指定したほうがいいでしょう。
5.2.1 観察の選択**
semi_join()
とanti_join()
という関数ではデータの結合ではなく、マッチングに応じた観察の選択が可能です。
semi_join(x, y)
:y
とマッチしたx
だけを返す。anti_join(x, y)
:y
とマッチしなかったx
だけを返す。