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
.
library("tidyverse")
# 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) %>%
mutate(
cond = glue::glue('{col} == "{searchString}" ~ "{code}"'),
cond = rlang::parse_exprs(cond)
)
# Logging, just to peek at what was created above.
str(caseArgs$cond)
# Apply the dynamically generated conditions.
data %>%
mutate(
coded = case_when(!!!caseArgs$cond)
)
}
recodeWithMap(ds, "description", recodeMap)