I'm trying to use the tidyverse to make a function that allows me to take a vector of column names (of class factor), count how many observations meet a certain condition (value == "yes"), mutate()
and make new columns using this sum so I can summarise the data later.
I have written a function that can do this for a single column, but I want to be able to pass a vector of column names of any length using all_of()
grammar to the function. When I try this, I get a new column with the same name as the vector (including my _count
suffix) not the values inside the vector.
This is similar to TimTeaFan's Post but I would like to pass a vector where length > 1.
I think I might need to use the (. . .) option in dplyr and some more rlang, but I haven't quite figured out the right combination. The function doesn't work when I substitute (. . .) for objective thanks to NSE. I've also tried variations of rlang::as_name()
and rlang::get_env()
. There was an outdated workbook that used purrr::map()
as well, but I haven't had any luck implementing it here.
I either got Error: Column x
is not found.
or Error: Promise has already been forced
Here is a reproducible example with data
dat <- tibble(category = rep(letters[1:10], 2),
intake = factor(c(rep("no", 12), rep("yes", 8))),
outtake = factor(c(rep("yes", 11), rep("no", 9))),
pretake = factor(c(rep(c("no", "yes"), 10))))
yessum <- function(.data, objective) {
.data %>%
dplyr::mutate("{{objective}}_count" := sum(
ifelse(
unlist(!!rlang::ensym(objective)) == "yes", 1, 0)))
}
dat %>%
group_by(category) %>%
yessum(intake)
I want to be able to pass a vector of certain column names to yessum and receive a set of new columns just like intake_new
but named outtake_new
and pretake_new
.
Here's what currently happens when I try that:
vars <- c("intake", "outtake", "pretake")
dat %>%
group_by(category) %>%
yessum(vars)
Any and all help is welcome!