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\$
4
  • 1
    \$\begingroup\$ Are you looking for rlang::quo_name(var)? \$\endgroup\$ Commented Oct 6, 2017 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
    Commented Oct 6, 2017 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\$ Commented Oct 6, 2017 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
    Commented Oct 6, 2017 at 9:49

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.