library(tidyverse)多対多の動作、確認しておきましょう。
ta_left <- tribble(
~id, ~x,
1 , 11,
2 , 12,
3 , 13,
2 , 14,
1 , 15
)
ta_right <- tribble(
~id, ~y,
1 , "a",
2 , "b1",
2 , "b2",
3 , "c"
)
ta_left# A tibble: 5 × 2
id x
<dbl> <dbl>
1 1 11
2 2 12
3 3 13
4 2 14
5 1 15
ta_right# A tibble: 4 × 2
id y
<dbl> <chr>
1 1 a
2 2 b1
3 2 b2
4 3 c
ta_ta <- ta_left %>%
left_join(ta_right, by="id")Warning in left_join(., ta_right, by = "id"): Detected an unexpected many-to-many relationship between `x` and `y`.
ℹ Row 2 of `x` matches multiple rows in `y`.
ℹ Row 2 of `y` matches multiple rows in `x`.
ℹ If a many-to-many relationship is expected, set `relationship =
"many-to-many"` to silence this warning.
ta_ta# A tibble: 7 × 3
id x y
<dbl> <dbl> <chr>
1 1 11 a
2 2 12 b1
3 2 12 b2
4 3 13 c
5 2 14 b1
6 2 14 b2
7 1 15 a
いかがでしょうか?
結合後の表、もともとのta_leftの行数が
nrow(ta_left)[1] 5
であるのに対して、
nrow(ta_ta)[1] 7
へと増加しており、行が水増しされたことが確認できます。
このように、結合前のデータと結合後のデータをnrow関数で行数の確認をして、不一致であれば、他対他の結合がおこなわれてしまっていることがわかります。
もし、結合するまえに他対他になるかを調べたい場合は、count関数やdistinct関数を利用しても良いかもしれません。
特に、右側、結合する方の表のIDが複数存在する場合は他対他になってしまうので、
ta_right %>% count(id)# A tibble: 3 × 2
id n
<dbl> <int>
1 1 1
2 2 2
3 3 1
ta_right %>% count(id) %>% filter(n > 1)# A tibble: 1 × 2
id n
<dbl> <int>
1 2 2
としてあげて、nが1より大きいものがないかを確認しましょう。今回は一目瞭然ですが、何全行もあったりするとこれで重複しているものを発見できます。
実例をみのであれば、
test <- tibble(
id = sample(1:300, 300, replace=TRUE),
val = rnorm(300, 100, 20)
)こんな300行のデータに対して重複しているidを調べたい場合、
test %>% count(id) %>% filter(n > 1)# A tibble: 76 × 2
id n
<int> <int>
1 6 2
2 9 2
3 14 2
4 23 2
5 31 3
6 32 2
7 37 5
8 40 2
9 54 2
10 64 3
# ℹ 66 more rows
で重複しているIDと、その重複回数、nを瞬時に調べることができました。(尚、sampleやrnorm関数はランダムに数字がでてくるので、実行結果は皆さんのものと違います。)
以上、多対多の結合でした。