Search code examples
rpurrrdplyrrlang

Can mutate_at name a variable according to a wrapped function name? (dplyr + rlang question)


I want to create a function that mutates all variables specified in ... with a particular metric specified by the metric argument. I use mutate_at in the function and want it to rename the variable with "var.functionname". The function is as follows:

seasonAggregator <- function(.data, ..., metric = "sum") {
  # all variables in ... will be accumulated
  metric <- sym(metric)
  name <- ensym(metric)
  print(paste0("Metric for accumulation was: ", metric))
  .data <- .data %>% mutate_at(vars(...), .funs = list(!!name := metric)) # HERE IS THE ISSUE
  return(.data)
}

How can I specify the function in the metric argument as such, that the mutate_at uses the name of the function to rename the variables?

Best Moritz!


Solution

  • @Moody_Mudskipper is correct. You want to use rlang::list2() which supports quasiquotation. Also, you probably want summarize_at, not mutate_at, since you're accumulating via sum.

    seasonAggregator <- function(.data, ..., metric = "sum") {
      ## all variables in ... will be accumulated
      print(paste0("Metric for accumulation was: ", metric))
      .data <- .data %>% 
          summarize_at(vars(...), .funs = rlang::list2(!!metric := sym(metric)))
      return(.data)
    }
    
    seasonAggregator( mtcars, mpg, cyl )
    # [1] "Metric for accumulation was: sum"
    #   mpg_sum cyl_sum
    # 1   642.9     198
    
    seasonAggregator( mtcars, mpg, cyl, metric="mean" )
    # [1] "Metric for accumulation was: mean"
    #   mpg_mean cyl_mean
    # 1 20.09062   6.1875