Skip to content

Instantly share code, notes, and snippets.

@MyKo101
Last active July 15, 2020 00:16
Show Gist options
  • Save MyKo101/0a82ca8fd450e82df29311148ab53f8a to your computer and use it in GitHub Desktop.
Save MyKo101/0a82ca8fd450e82df29311148ab53f8a to your computer and use it in GitHub Desktop.
Function to perform case_when() to produce multiple colums
food <- tibble(item=c("apple","baguette","zucchini","mushrooms"))
multi_case_when <- function(.x,.names,...) {
require(rlang)
require(magrittr)
require(purrr)
.dots <- enquos(...)
len_res <- .dots %>%
map_int(. %>%
quo_get_expr %>%
extract2(3) %>%
extract(-1) %>%
length)
if(any(len_res != length(.names))) {
abort("Lengths in multi_case_when() must be all equal")
}
eval_env <- list2env(.x,parent=caller_env())
.dots <- map(.dots,~quo_set_env(.,eval_env))
.y <- .x
for(i in 1:length(.names)){
.exprs <- structure(map(.dots,
function(dot_element) {
dot_element %>%
quo_get_expr %>%
inset2(3,extract2(.,c(3,i+1))) %>%
quo_set_expr(dot_element,.)
}),
class=c("quosures","list"))
.y$.res <- case_when(!!!.exprs)
names(.y)[names(.y) == ".res"] <- .names[i]
}
.y
}
food %>%
multi_case_when(
c("type","price"),
item == "apple" ~ c("fruit",1),
item == "baguette" ~ c("bread",2),
item == "zucchini" ~ c("vegetable",0.5)
)
# A tibble: 4 x 3
# item type price
# <chr> <chr> <dbl>
# 1 apple fruit 1
# 2 baguette bread 2
# 3 zucchini vegetable 0.5
# 4 mushrooms NA NA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment