I am trying to write a function in tidyverse/dplyr
that I want to eventually use with lapply
(or map
). (I had been working on it to answer
Let me first point out that in your initial report
function, you can use quo_name
to convert the quosure into a string, which you can then use in mutate
like the following:
library(dplyr)
library(rlang)
report <- function(report_cat){
report_cat <- enquo(report_cat)
sample_data %>%
group_by(!!report_cat, YEAR) %>%
summarize(num=n(),total=sum(AMOUNT)) %>%
rename(REPORT_VALUE = !!report_cat) %>%
mutate(REPORT_CATEGORY = quo_name(report_cat))
}
report(REPORT_CODE)
Now, to address your question of "how to feed a list of unquoted strings through lapply
or map
to make it work inside dplyr
functions", I propose two ways of doing it.
rlang::sym
to parse your strings and unquote it when feeding into lapply
or map
library(purrr)
cat.list <- c("REPORT_CODE","PAYMENT_METHOD","INBOUND_CHANNEL","AMOUNT_CAT")
map_df(cat.list, ~report(!!sym(.)))
or with syms
you can parse all elements of a vector at once:
map_df(syms(cat.list), ~report(!!.))
Result:
# A tibble: 27 x 5
# Groups: REPORT_VALUE [16]
REPORT_VALUE YEAR num total REPORT_CATEGORY
1 J FY14 1 25 REPORT_CODE
2 Q FY16 1 1 REPORT_CODE
3 Q FY17 1 100 REPORT_CODE
4 R FY17 1 50 REPORT_CODE
5 R FY18 2 75 REPORT_CODE
6 S FY17 2 400 REPORT_CODE
7 S FY18 2 530 REPORT_CODE
8 Check FY14 1 25 PAYMENT_METHOD
9 Check FY17 1 50 PAYMENT_METHOD
10 Check FY18 2 55 PAYMENT_METHOD
# ... with 17 more rows
report
function by placing lapply
or map
inside so that report
can do NSEreport <- function(...){
report_cat <- quos(...)
map_df(report_cat, function(x) sample_data %>%
group_by(!!x, YEAR) %>%
summarize(num=n(),total=sum(AMOUNT)) %>%
rename(REPORT_VALUE = !!x) %>%
mutate(REPORT_CATEGORY = quo_name(x)))
}
By placing map_df
inside report
, you can take advantage of quos
, which converts ...
to list of quosures. They are then fed into map_df
and unquoted one by one using !!
.
report(REPORT_CODE, PAYMENT_METHOD, INBOUND_CHANNEL, AMOUNT_CAT)
Another advantage of writing it like this is that you can also supply a vector of string symbols and splice them using !!!
like the following:
report(!!!syms(cat.list))
Result:
# A tibble: 27 x 5
# Groups: REPORT_VALUE [16]
REPORT_VALUE YEAR num total REPORT_CATEGORY
1 J FY14 1 25 REPORT_CODE
2 Q FY16 1 1 REPORT_CODE
3 Q FY17 1 100 REPORT_CODE
4 R FY17 1 50 REPORT_CODE
5 R FY18 2 75 REPORT_CODE
6 S FY17 2 400 REPORT_CODE
7 S FY18 2 530 REPORT_CODE
8 Check FY14 1 25 PAYMENT_METHOD
9 Check FY17 1 50 PAYMENT_METHOD
10 Check FY18 2 55 PAYMENT_METHOD
# ... with 17 more rows