Using a data frame of replacement values to replace values in another data frame in R?

I have a data frame of values:

df <- structure(list(X1 = 1:2, X2 = c(1L, 3L), X3 = 2:3), class = "data.frame", row.names = c(NA, -2L))

  X1 X2 X3
1  1  1  2
2  2  3  3

And a data frame containing replacement values:

replacement_values <- structure(list(num = c("1", "2", "3"), . = c("cat", 
"dog", "mouse")), row.names = c(NA, 
-3L), class = "data.frame")

  num     .
1   1   cat
2   2   dog
3   3 mouse

For example, every time the number "1" is found in the first data frame, I would like it replaced by the word "cat", every time "2" is found I want it replaced by "dog" and every time "3" is found I want it replaced by "mouse". So Ideally I would end up with a data frame that looks like this:

    X1    X2    X3
1  cat   cat   dog
2  dog mouse mouse

I could do it like this but it’s very long winded and doesn’t use the replacement_values data frame:

df <- df %>%
    dplyr::mutate(
        X1 = X1 %>% 
            gsub("1", "cat", .) %>%
            gsub("2", "dog", .) %>%
            gsub("3", "mouse", .),
        X2 = X2 %>% 
            gsub("1", "cat", .) %>%
            gsub("2", "dog", .) %>%
            gsub("3", "mouse", .),
        X3 = X3 %>% 
            gsub("1", "cat", .) %>%
            gsub("2", "dog", .) %>%
            gsub("3", "mouse", .)
            )

Is there a better way?

>Solution :

library(tidyverse)
replacement_values <-
  structure(list(
    num = c("1", "2", "3"),
    . = c("cat",
          "dog", "mouse")
  ),
  row.names = c(NA,-3L),
  class = "data.frame")

df <-
  structure(list(
    X1 = 1:2,
    X2 = c(1L, 3L),
    X3 = 2:3
  ),
  class = "data.frame",
  row.names = c(NA,-2L))

map_df(df, ~replacement_values$.[match(.x, table = replacement_values$num)])
#> # A tibble: 2 x 3
#>   X1    X2    X3   
#>   <chr> <chr> <chr>
#> 1 cat   cat   dog  
#> 2 dog   mouse mouse

Created on 2022-09-16 with reprex v2.0.2

Leave a Reply