Search code examples
rmergelookup

How to match multiple columns based on lookup table


I have the following two data frames:

lookup <- data.frame(id = c("A", "B", "C"),
                     price = c(1, 2, 3))

results <- data.frame(price_1 = c(2,2,1),
                      price_2 = c(3,1,1))

I now want to go through all columns of results and add the respective matching id from lookup as new columns. So I first want to take the price_1 column and find the ids (here: "B", "B", "A") and add it as a new column to results and then I want to do the same for the price_2 column.

My real-life case would need to match 20+ columns, so I want to avoid a hard-coded manual solution and are looking for a dynamic approach, ideally in the tidyverse.

results <- results %>%
  left_join(., lookup, by = c("price_1" = "id")

would give me the manual solution for the first column and I could repeat this with the second column, but I'm wondering if I can do this automatically for all my results columns.

Expected output:

price_1 price_2 id_1 id_2
2       3       "B"  "C"
2       1       "B"  "A"
1       1       "A"  "A"

Solution

  • We could unlist the dataframe and match directly.

    new_df <- results
    names(new_df) <- paste0("id", seq_along(new_df))
    new_df[] <- lookup$id[match(unlist(new_df), lookup$price)]
    cbind(results, new_df)
    
    #  price_1 price_2 id1 id2
    #1       2       3   B   C
    #2       2       1   B   A
    #3       1       1   A   A
    

    In dplyr, we can do

    library(dplyr)
    bind_cols(results, results %>%  mutate_all(~lookup$id[match(., lookup$price)]))