151  実践 left_join

library(tidyverse)

それでは、left_join、実践していきましょう。

まずスライドで利用していたデータを作っておきます。

library(tidyverse)

dat <- tribble(
  ~date   , ~patient_id, ~kensa_id, ~value,
  "2020/4/1", 1          , "a342"   , 6.8   ,
  "2020/4/1", 2          , "a342"   , 5.6   ,
  "2020/4/2", 1          , "a341"   , 52    ,
  "2020/4/2", 3          , "a340"   , 32
)

ここで利用しているtribble関数、チルダ列名とかいて、その後、データを入力することで「表の形」そのままでtibbleが作れるので、こういう風に、データの位置を考えながら表を作成しないといけないときに結構便利です。

kensa <- tribble(
  ~kensa_id, ~kensa_name, ~unit,
  "a340"   , "AST"      , "IU"       ,
  "a341"   , "ALT"      , "IU"       ,
  "a342"   , "HbA1c"    , "%"         
)

dat
# A tibble: 4 × 4
  date     patient_id kensa_id value
  <chr>         <dbl> <chr>    <dbl>
1 2020/4/1          1 a342       6.8
2 2020/4/1          2 a342       5.6
3 2020/4/2          1 a341      52  
4 2020/4/2          3 a340      32  
kensa
# A tibble: 3 × 3
  kensa_id kensa_name unit 
  <chr>    <chr>      <chr>
1 a340     AST        IU   
2 a341     ALT        IU   
3 a342     HbA1c      %    

まず、これらのデータを結合していきましょう。

left_join(dat, kensa, by = "kensa_id")
# A tibble: 4 × 6
  date     patient_id kensa_id value kensa_name unit 
  <chr>         <dbl> <chr>    <dbl> <chr>      <chr>
1 2020/4/1          1 a342       6.8 HbA1c      %    
2 2020/4/1          2 a342       5.6 HbA1c      %    
3 2020/4/2          1 a341      52   ALT        IU   
4 2020/4/2          3 a340      32   AST        IU   

できました!

パイプ関数を利用するのであれば、

dat %>% 
  left_join(kensa, by = "kensa_id")
# A tibble: 4 × 6
  date     patient_id kensa_id value kensa_name unit 
  <chr>         <dbl> <chr>    <dbl> <chr>      <chr>
1 2020/4/1          1 a342       6.8 HbA1c      %    
2 2020/4/1          2 a342       5.6 HbA1c      %    
3 2020/4/2          1 a341      52   ALT        IU   
4 2020/4/2          3 a340      32   AST        IU   

でもOKです。パイプは一つ目のアーギュメントとして扱われるので、左側の表  %>%  left_join(右側の表…)となっている必要があることに注意が必要です。

kensa2 <- kensa %>% rename(id = kensa_id)

kensa2
# A tibble: 3 × 3
  id    kensa_name unit 
  <chr> <chr>      <chr>
1 a340  AST        IU   
2 a341  ALT        IU   
3 a342  HbA1c      %    

ここで、

colnames(dat)
[1] "date"       "patient_id" "kensa_id"   "value"     
colnames(kensa2)
[1] "id"         "kensa_name" "unit"      

左と、右の表の結合したい列の名前が違う場合も処理しておきましょう。

dat %>% 
  left_join(kensa2, by="kensa_id")
Error in `left_join()`:
! Join columns in `y` must be present in the data.
✖ Problem with `kensa_id`.

だと、右側にkensa_idという名前の列がないのでエラーになります。

dat %>% 
  left_join(kensa2, by=c("kensa_id"="id"))
# A tibble: 4 × 6
  date     patient_id kensa_id value kensa_name unit 
  <chr>         <dbl> <chr>    <dbl> <chr>      <chr>
1 2020/4/1          1 a342       6.8 HbA1c      %    
2 2020/4/1          2 a342       5.6 HbA1c      %    
3 2020/4/2          1 a341      52   ALT        IU   
4 2020/4/2          3 a340      32   AST        IU   

このようにベクトルで与えてあげるとうまくくっつきました。

このベクトルで与えてあげる方法は、

test1 <- tribble(
  ~idA, ~idB, ~value1,
  1   , 1   , 10     ,
  1   , 2   , 11     ,
  2   , 1   , 12     ,
  2   , 2   , 13     ,
  1   , 2   , 14     ,
  2   , 2   , 15    
  
)

test2 <- tribble(
  ~category, ~id, ~value2,
  1        , 1  , "dog" ,
  1        , 2  , "cat" ,
  2        , 1  , "pig" ,
  2        , 2  , "cow"
)

test2
# A tibble: 4 × 3
  category    id value2
     <dbl> <dbl> <chr> 
1        1     1 dog   
2        1     2 cat   
3        2     1 pig   
4        2     2 cow   

二つ以上の列を基準として結合する場合にも使えて、

test1 %>% 
  left_join(test2, by=c("idA"="category", "idB"="id"))
# A tibble: 6 × 4
    idA   idB value1 value2
  <dbl> <dbl>  <dbl> <chr> 
1     1     1     10 dog   
2     1     2     11 cat   
3     2     1     12 pig   
4     2     2     13 cow   
5     1     2     14 cat   
6     2     2     15 cow   

こんな風にくっつきます。

また、ここで、

samename1 <- test1 %>% rename(value = value1)
samename2 <- test2 %>% rename(value = value2)

colnames(samename1)
[1] "idA"   "idB"   "value"
colnames(samename2)
[1] "category" "id"       "value"   

で、同じ名前の列が結合した後に出現する場合もみておきましょう。

byの中身はここではあまり関係ないので、変数に収納しておきます。

join_this <- c("idA"="category", "idB"="id")

samename1 %>% 
  left_join(samename2, by=join_this)
# A tibble: 6 × 4
    idA   idB value.x value.y
  <dbl> <dbl>   <dbl> <chr>  
1     1     1      10 dog    
2     1     2      11 cat    
3     2     1      12 pig    
4     2     2      13 cow    
5     1     2      14 cat    
6     2     2      15 cow    

どうでしょうか?

左と右の表にそれぞれ、結合に用いない列名が同じ、valueというものがあるため、left_joinすると、自動的に、value.x value.yと名前が変わっています。この動作、コントロールすることも可能で、

samename1 %>% 
  left_join(samename2, 
            by=join_this, 
            suffix=c("__left","__right"))
# A tibble: 6 × 4
    idA   idB value__left value__right
  <dbl> <dbl>       <dbl> <chr>       
1     1     1          10 dog         
2     1     2          11 cat         
3     2     1          12 pig         
4     2     2          13 cow         
5     1     2          14 cat         
6     2     2          15 cow         

と、このようにsuffixアーギュメントに左、右の順番で、列名の後ろにくっつけたい文字列を指定してあげることができます。