Search code examples
rpurrr

Pass list of arguments to create custom joins with map in R


I'd like to use map to pass a list of arguments as criteria for joins.

I've tried map2, but I'm open to using rowwise, or even a non iterative method.

library(tidyverse)
tbl1 <- diamonds %>% head(100)
tbl2 <- diamonds %>% head(400)

list_1 <- c("cut", "color")
list_2 <- c("cut", "color")

map2(
  .x=list_1
  ,.y=list_2,
  ,.f =
    ~left_join(
  tbl1
  ,tbl2
  ,by=join_by(.x==.y))
  ,multiple="first"
  )

Solution

  • Two things:

    1. We need to evaluate .x and .y using !!
    2. The parentheses in the left_join() call were slightly wrong
    library(tidyverse)
    
    tbl1 <- diamonds %>% head(100)
    tbl2 <- diamonds %>% head(400)
    
    list_1 <- c("cut", "color")
    list_2 <- c("cut", "color")
    
    map2(
      .x=list_1,
      .y=list_2,
      .f =
        ~left_join(
          tbl1,
          tbl2,
          by=join_by(!! .x == !! .y),
      multiple="first")
      )
    #> [[1]]
    #> # A tibble: 100 × 19
    #>    carat.x cut       color.x clarity.x depth.x table.x price.x   x.x   y.x   z.x
    #>      <dbl> <ord>     <ord>   <ord>       <dbl>   <dbl>   <int> <dbl> <dbl> <dbl>
    #>  1    0.23 Ideal     E       SI2          61.5      55     326  3.95  3.98  2.43
    #>  2    0.21 Premium   E       SI1          59.8      61     326  3.89  3.84  2.31
    #>  3    0.23 Good      E       VS1          56.9      65     327  4.05  4.07  2.31
    #>  4    0.29 Premium   I       VS2          62.4      58     334  4.2   4.23  2.63
    #>  5    0.31 Good      J       SI2          63.3      58     335  4.34  4.35  2.75
    #>  6    0.24 Very Good J       VVS2         62.8      57     336  3.94  3.96  2.48
    #>  7    0.24 Very Good I       VVS1         62.3      57     336  3.95  3.98  2.47
    #>  8    0.26 Very Good H       SI1          61.9      55     337  4.07  4.11  2.53
    #>  9    0.22 Fair      E       VS2          65.1      61     337  3.87  3.78  2.49
    #> 10    0.23 Very Good H       VS1          59.4      61     338  4     4.05  2.39
    #> # ℹ 90 more rows
    #> # ℹ 9 more variables: carat.y <dbl>, color.y <ord>, clarity.y <ord>,
    #> #   depth.y <dbl>, table.y <dbl>, price.y <int>, x.y <dbl>, y.y <dbl>,
    #> #   z.y <dbl>
    #> 
    #> [[2]]
    #> # A tibble: 100 × 19
    #>    carat.x cut.x     color clarity.x depth.x table.x price.x   x.x   y.x   z.x
    #>      <dbl> <ord>     <ord> <ord>       <dbl>   <dbl>   <int> <dbl> <dbl> <dbl>
    #>  1    0.23 Ideal     E     SI2          61.5      55     326  3.95  3.98  2.43
    #>  2    0.21 Premium   E     SI1          59.8      61     326  3.89  3.84  2.31
    #>  3    0.23 Good      E     VS1          56.9      65     327  4.05  4.07  2.31
    #>  4    0.29 Premium   I     VS2          62.4      58     334  4.2   4.23  2.63
    #>  5    0.31 Good      J     SI2          63.3      58     335  4.34  4.35  2.75
    #>  6    0.24 Very Good J     VVS2         62.8      57     336  3.94  3.96  2.48
    #>  7    0.24 Very Good I     VVS1         62.3      57     336  3.95  3.98  2.47
    #>  8    0.26 Very Good H     SI1          61.9      55     337  4.07  4.11  2.53
    #>  9    0.22 Fair      E     VS2          65.1      61     337  3.87  3.78  2.49
    #> 10    0.23 Very Good H     VS1          59.4      61     338  4     4.05  2.39
    #> # ℹ 90 more rows
    #> # ℹ 9 more variables: carat.y <dbl>, cut.y <ord>, clarity.y <ord>,
    #> #   depth.y <dbl>, table.y <dbl>, price.y <int>, x.y <dbl>, y.y <dbl>,
    #> #   z.y <dbl>
    

    Created on 2023-06-28 with reprex v2.0.2