153  色々なjoin関数

library(tidyverse)

ここまで、left_joinの話ばかりでしたが、色々なjoin関数が用意されています。

原則、left_joinがわかれば、たいてい何とかなるのですが、ここで、他の関数を紹介しておきます。

dat1 <- tribble(
  ~id, ~val1,
  1  , 11,
  2  , 12,
  2  , 12,
  4  , 14,
  1  , 15,
  5  , 16
)

dat2 <- tribble(
  ~id, ~val2,
  1  , 21,
  2  , 22,
  3  , 23,
  4  , 24,
  5  , 25
)

まず、これまでのleft_joinはこれです。これは、左側にあるIDを残すというイメージです

left_join(dat1, dat2, by="id")
# A tibble: 6 × 3
     id  val1  val2
  <dbl> <dbl> <dbl>
1     1    11    21
2     2    12    22
3     2    12    22
4     4    14    24
5     1    15    21
6     5    16    25

leftではなく,right_joinというのもあって

right_join(dat2, dat1, by="id")
# A tibble: 6 × 3
     id  val2  val1
  <dbl> <dbl> <dbl>
1     1    21    11
2     1    21    15
3     2    22    12
4     2    22    12
5     4    24    14
6     5    25    16

left_joinの左向けの結合ではなく、右向けの結合になります。

right_join(dat1, dat2, by="id")
# A tibble: 7 × 3
     id  val1  val2
  <dbl> <dbl> <dbl>
1     1    11    21
2     2    12    22
3     2    12    22
4     4    14    24
5     1    15    21
6     5    16    25
7     3    NA    23

idはdat2が1から5まで一個ずつ、dat1が1が2つ、2が2つ、3が0こで、4,5が1個ずつなので、dat2の1と2が水増しされてるのと、3が「あたらない」ので、NAで表示されています。right_joinは、右側にあるIDが残るという風なイメージでもよいと思います。

後は、

dat3 <- tribble(
  ~id, ~val3,
  1  ,  "a",
  3  ,  "b",
  4  ,  "c"
)

dat4 <- tribble(
  ~id, ~val4,
  3  , "A",
  5  , "B",
  6  , "C"
)

というデータがあったとして、

左のIDが残る、

left_join(dat3 , dat4, by="id")
# A tibble: 3 × 3
     id val3  val4 
  <dbl> <chr> <chr>
1     1 a     <NA> 
2     3 b     A    
3     4 c     <NA> 

右のIDが残る、

right_join(dat3, dat4, by="id")
# A tibble: 3 × 3
     id val3  val4 
  <dbl> <chr> <chr>
1     3 b     A    
2     5 <NA>  B    
3     6 <NA>  C    

両方にあるIDだけ残る、

inner_join(dat3, dat4, by="id")
# A tibble: 1 × 3
     id val3  val4 
  <dbl> <chr> <chr>
1     3 b     A    

どちらか片方にあるIDだけ残る、

full_join(dat3, dat4, by="id")
# A tibble: 5 × 3
     id val3  val4 
  <dbl> <chr> <chr>
1     1 a     <NA> 
2     3 b     A    
3     4 c     <NA> 
4     5 <NA>  B    
5     6 <NA>  C    

という関数もあります。

他にも、filtering joinと呼ばれる、抽出するためのsemi_join関数やanti_join関数もありますが、とりあえず、現時点では、結合のためのjoinを理解できるとよいと思います。