4
\$\begingroup\$

Background

I've wrote a trivial wrapper function summarising variable by group for dplyr. I would like to handle quosures more efficiently. In particular, I've a hunch that rlang::UQE(var) could be written more efficiently.

Code

#' @title Create a simple sum by grouping variables
#'
#' @description
#' \code{sum_by_group} is simple wrapper groping variables and deriving sum
#'
#' @details
#' This is a primitive utility function performing
#'   \code{group_by %>% summarise(sum(.)) %>% ungroup} on passed variables.
#'
#' @param df A data.frame or tibble to conduct summary on
#' @param var A numeric variable to summarise
#' @param ... Grouping variables.
#'
#' @return A \code{data.frame} with grouping variables and summary.
#'
#' @import rlang
#'
#' @export
#'
#' @examples
#' mtcars %>% sum_by_group(disp, cyl, am)
sum_by_group <- function(df, var, ...) {
    # Take variables to group by
    group_vars <- quos(...)
    # Take sum variable
    var <- enquo(var)
    # Group and summarise
    df %>%
        group_by(!!!group_vars) %>%
        summarise(sum_var = sum(!!var)) %>%
        ungroup() %>%
        # Rename variable
        setNames(gsub("sum_var",
                      paste(rlang::UQE(var), "sum", sep = "_"), names(.)))

}

Example

>> mtcars %>% sum_by_group(var = disp, am, cyl)
# A tibble: 6 x 3
     am   cyl disp_sum
  <dbl> <dbl>    <dbl>
1     0     4    407.6
2     0     6    818.2
3     0     8   4291.4
4     1     4    748.9
5     1     6    465.0
6     1     8    652.0
\$\endgroup\$
  • 1
    \$\begingroup\$ Are you looking for rlang::quo_name(var)? \$\endgroup\$ – hplieninger Oct 6 '17 at 8:08
  • \$\begingroup\$ @hplieninger Thanks for suggestion; yes that seems like a wiser approach than the one I took. I don't make often use of quosures so wanted to see how this problem could be solved in a cleaner manner. TBH, I don't like the whole setNames(gsub(...)) call. I reckon efficient use of quosures should allow for avoiding this. \$\endgroup\$ – Konrad Oct 6 '17 at 8:15
  • 1
    \$\begingroup\$ In the vignette, there is an example avoiding setNames(), but it still involves paste() (combined with :=). Personally, I would like to be able to use name-value pairs like in mutate() or summarise(), but I have not yet figured out how to do it. \$\endgroup\$ – hplieninger Oct 6 '17 at 9:33
  • 1
    \$\begingroup\$ I reckon, it's also possible to do: mutate(!!quo_name(whats_passed_from_enquo)... but it's ugly. \$\endgroup\$ – Konrad Oct 6 '17 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.