tidyverseで2つのデータフレームの結合は、dplyrパッケージのjoin系関数を使います。キーが共通する部分を結合するinner_join関数がよく使われます。2つのデータフレームの結合条件によって、その他のjoin系関数を使い分けます。2つのテーブルでデータが揃わない場合は「NA」になるので、適切に処理します。Rの標準的な操作の場合は、merge関数を使います。
- inner_join: 指定したキーについて、どちらのデータフレームにも存在する行を結合
- left_join: 指定したキーについて、左側に書いたデータフレームに存在する行を結合
- right_join: 指定したキーについて、右側に書いたデータフレームに存在する行を結合
- full_join: 指定したキーについて、データフレームのいずれかに存在するキーの行を結合
inner_join
inner_join関数は、指定したキーについて「どちらのデータフレームにも存在する行」を結合します。tidyverseパッケージをロードすると使えるようになります。
書式
inner_join関数は、第1引数に左側データフレーム、第2引数に右側データフレームを指定します。同じ列名で自動で結合されますが、大文字・小文字の違いなどで列名が異なる場合、byキーワードで指定した列を結合します。尚、パイプ(%>%)を使って連続的に処理を記述する場合は、第1引数のデータは省略することができます。
共通の列で結合する
inner_join関数に結合するデータフレームを指定して、どちらのデータフレームにも存在する行を結合します。共通の列名があるのでデータフレームを指定するだけで結合可能です。
1: > library(tidyverse) 2: 3: > my_data <- iris %>% slice(1, 51, 101) 4: > my_data$Species <- as.character(my_data$Species) 5: Sepal.Length Sepal.Width Petal.Length Petal.Width Species 6: 1 5.1 3.5 1.4 0.2 setosa 7: 2 7.0 3.2 4.7 1.4 versicolor 8: 3 6.3 3.3 6.0 2.5 virginica
1: > id <- tibble( 2: + num = c(1, 2, 3), 3: + Species = c("setosa", "virginica", "other") 4: + ) 5: 6: > id 7: # A tibble: 3 x 2 8: num Species 9: <dbl> <chr> 10: 1 1 setosa 11: 2 2 virginica 12: 3 3 other
1: > id %>% inner_join(my_data) 2: # A tibble: 2 x 6 3: num species Sepal.Length Sepal.Width Petal.Length Petal.Width 4: <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 5: 1 1 setosa 5.1 3.5 1.4 0.2 6: 2 2 virginica 6.3 3.3 6 2.5
異なる列名で結合する
異なる列名で結合する場合、「by」で結合する列名をそれぞれ指定します。他のjoin系関数でも同様の指定方法です。
1: > id <- tibble( 2: + num = c(1, 2, 3), 3: + species = c("setosa", "virginica", "other") 4: + ) 5: 6: > id 7: # A tibble: 3 x 2 8: num Species 9: <dbl> <chr> 10: 1 1 setosa 11: 2 2 virginica 12: 3 3 other
1: > id %>% inner_join(my_data, by=c("species" = "Species")) 2: # A tibble: 2 x 6 3: num species Sepal.Length Sepal.Width Petal.Length Petal.Width 4: <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 5: 1 1 setosa 5.1 3.5 1.4 0.2 6: 2 2 virginica 6.3 3.3 6 2.5
left_join
left_join関数は、指定したキーについて「左側に書いたデータフレームに存在する行」を結合します。右側に存在しないデータは、「NA」になります。
1: > id %>% left_join(my_data) 2: # A tibble: 3 x 6 3: num species Sepal.Length Sepal.Width Petal.Length Petal.Width 4: <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 5: 1 1 setosa 5.1 3.5 1.4 0.2 6: 2 2 virginica 6.3 3.3 6 2.5 7: 3 3 other NA NA NA NA
right_join
right_join関数は、指定したキーについて「右側に書いたデータフレームに存在する行」を結合します。左側に存在しないデータは、「NA」になります。
1: > id %>% right_join(my_data) 2: # A tibble: 3 x 6 3: num species Sepal.Length Sepal.Width Petal.Length Petal.Width 4: <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 5: 1 1 setosa 5.1 3.5 1.4 0.2 6: 2 NA versicolor 7 3.2 4.7 1.4 7: 3 2 virginica 6.3 3.3 6 2.5
full_join
full_join関数は、指定したキーについて「データフレームのいずれかに存在するキーの行」を結合します。左側・右側に存在しないデータは、「NA」になります。
1: > id %>% full_join(my_data) 2: # A tibble: 4 x 6 3: num species Sepal.Length Sepal.Width Petal.Length Petal.Width 4: <dbl> <chr> <dbl> <dbl> <dbl> <dbl> 5: 1 1 setosa 5.1 3.5 1.4 0.2 6: 2 2 virginica 6.3 3.3 6 2.5 7: 3 3 other NA NA NA NA 8: 4 NA versicolor 7 3.2 4.7 1.4
NA の処理
join系関数で、データが揃わない場合は「NA」になります。replace_na関数を使うことで、「NA」を置き換えることができます。replace_na関数に「列名・置き換え」のセットを複数指定することができます。
1: > id %>% full_join(my_data) %>% replace_na(list(num="---", Sepal.Length="--", Petal.Width="--")) 2: Joining, by = "Species" 3: # A tibble: 4 x 6 4: num Species Sepal.Length Sepal.Width Petal.Length Petal.Width 5: <chr> <chr> <chr> <dbl> <dbl> <chr> 6: 1 1 setosa 5.1 3.5 1.4 0.2 7: 2 2 virginica 6.3 3.3 6 2.5 8: 3 3 other -- NA NA -- 9: 4 --- versicolor 7 3.2 4.7 1.4
Rの標準的な操作
2つのデータフレームの結合を行う場合、Rの標準的な方法ではmerge関数を使います。引数に結合するデータフレームを与えます。allオプションで、共通する行だけを残すか、どちらにしか存在しない行も残すかを指定できます。共通する列名がある場合、結合は自動で対応づけが行われます。共通しない列名で結合する場合、列名をそれぞれ指定します。
共通の列名で結合する場合
結合につかう列名を指定する必要はありません。
1: > id <- data.frame(num = c(1, 2, 3), 2: + Species = c("setosa", "virginica", "other") 3: + ) 4: > id 5: num Species 6: 1 1 setosa 7: 2 2 virginica 8: 3 3 other 9: 10: > my_data <- iris[c(1, 51, 101),] 11: > my_data 12: Sepal.Length Sepal.Width Petal.Length Petal.Width Species 13: 1 5.1 3.5 1.4 0.2 setosa 14: 51 7.0 3.2 4.7 1.4 versicolor 15: 101 6.3 3.3 6.0 2.5 virginica 16: 17: > merge(id, my_data) 18: Species num Sepal.Length Sepal.Width Petal.Length Petal.Width 19: 1 setosa 1 5.1 3.5 1.4 0.2 20: 2 virginica 2 6.3 3.3 6.0 2.5 21: 22: merge(id, my_data, all=T) 23: Species num Sepal.Length Sepal.Width Petal.Length Petal.Width 24: 1 other 3 NA NA NA NA 25: 2 setosa 1 5.1 3.5 1.4 0.2 26: 3 virginica 2 6.3 3.3 6.0 2.5 27: 4 versicolor NA 7.0 3.2 4.7 1.4
異なるの列名で結合する場合
結合につかう列名をそれぞれ指定します。「by.x」、「by.y」で指定します。
1: colnames(id) <- c("num", "species") 2: > id 3: num species 4: 1 1 setosa 5: 2 2 virginica 6: 3 3 other 7: 8: merge(id, my_data, by.x="species", by.y="Species") 9: species num Sepal.Length Sepal.Width Petal.Length Petal.Width 10: 1 setosa 1 5.1 3.5 1.4 0.2 11: 2 virginica 2 6.3 3.3 6.0 2.5
まとめ
- tidyverseのdplyrパッケージで提供される、join系関数を使って2つのデータフレームの結合を行います。同じ列名があれば、キーを省略できます。
- 結合は条件によって関数を使い分けます。(inner_join, left_join, right_join, full_join)
- 結合でデータが揃わない場合は「NA」になるので、replace_na関数などを使って適切に処理します。
- Rの標準的な操作ではmerge関数を使います。