I'd like to make a simple function that takes a data frame and user supplied names for two columns in that data frame. The purpose would be to allow this to work easily with dplyr
pipes. It will produce a character vector of glued strings:
func <- function(data, last, first) {
last <- rlang::enquo(last)
first <- rlang::enquo(first)
glue::glue_data(data, "{!!last}, {!!first}")
}
I'd ideally like a user to be able to call:
df %>% func(lastName, firstName)
This would produce a character vector of multiple values formatted as Smith, John
.
My function currently does not work because the bang-bang operators don't work within the context of glue_data
. How can I work around this while still using NSE? The error I receive is:
Error: Quosures can only be unquoted within a quasiquotation context.
REPREX:
df <- data.frame(lastName = c("Smith", "Bond", "Trump"), firstName = c("John","James","Donald"))
> df
lastName firstName
1 Smith John
2 Bond James
3 Trump Donald
EXPECTED OUTPUT
> glue::glue_data(df, "{lastName}, {firstName}")
Smith, John
Bond, James
Trump, Donald
However, I would like to be able to achieve the expected output by using my function and calling:
df %>% func(lastName, firstName)
Above is a simplified version of my actual use case where I will actually be calling the glue
statement as a parameter in a follow on function:
biggerfn <- function(data, subject, first, last) {
subject <- rlang::enquo(subject)
first <- rlang::enquo(first)
last <- rlang::enquo(last)
data %>%
dplyr::distinct(!!subject, !!first, !!last) %>%
smallerfunc(!!subject, glue::glue_data(data, "{!!last}, {!!first}"))
}
I don't know if you're committed to glue
, but this can be easily accomplished using tidyr::unite
:
func <- function(data, last, first) {
data %>%
tidyr::unite(result, {{last}}, {{first}}, sep=", ")
}
df %>% func(lastName, firstName)
# result
# 1 Smith, John
# 2 Bond, James
# 3 Trump, Donald
# Optionally, follow up with:
# %>% dplyr::pull(result)
# to retrieve the column
Here, {{x}}
is a shorthand for !!enquo(x)
.