case_when pattern dynamically generated

Had a similar question to Create patterns list from df values for use in case_when but it seems the topic was closed with an answer covering an alternative rather than showing how to programatically generate the case_when conditions.

If anyone else encounters the needs, here's a way to do it with rlang.


# Table with one column called description.
ds <- tibble::tibble(
  description = c(letters, letters, LETTERS)

# We'll use this to dynamically create case_when conditions. What we want is if a or b to recode as fruit, if letters 3:10 then record as cars, etc.
recodeMap <- list(
 fruit = c("a", "b"),
 cars = letters[3:10],
 house = letters[11:15]

# Converts list above into a table
codeListUnnest <- function(codes) {
  tidyr::unnest(tibble::tibble(code = names(codes), searchString = codes), cols = c(searchString))

recodeWithMap <- function(data, col, recodes) {
  # Parses each row as an expression e.g. `description == "a" ~ "fruit"` 
  caseArgs <- codeListUnnest(recodes) %>% 
      cond = glue::glue('{col} == "{searchString}" ~ "{code}"'),
      cond = rlang::parse_exprs(cond)
  # Logging, just to peek at what was created above.

  # Apply the dynamically generated conditions.
  data %>%
      coded = case_when(!!!caseArgs$cond)
recodeWithMap(ds, "description", recodeMap)

Thanks, that's slick. Great pattern for doing a hash.