rfunctiondplyrtidyevalquasiquotes

tidyr use glue strings later in function


Tidy eval now supports glue strings

So this works great:

my_summarise5 <- function(data, mean_var ) {
  data %>% 
    mutate(
      "mean_{{mean_var}}" := mean({{ mean_var }}), 
    ) 
}

mtcars %>% my_summarise5(cyl)

But then

my_summarise5 <- function(data, mean_var ) {
  data %>% 
    mutate(
      "mean_{{mean_var}}" := mean({{ mean_var }}), 
    "mean_{{mean_var}}_plusone" :=  "mean_{{mean_var}}"+1
    )
}

mtcars %>% my_summarise5(cyl)

Throws

Error: Problem with `mutate()` input `mean_cyl_plusone`.
x non-numeric argument to binary

Would some 'paste' or 'glue' thing in the "mean_{{mean_var}}_plusone" := "mean_{{mean_var}}"+1 part fix this?

Note this is obviously not a useful case, its a MWE for the syntax. I actually want to define two new columns with different names, one which uses the other ... otherwise I have to repeat and it also gets messy.


Solution

  • I love the tidyverse, but using base R can have a big payoff, by making your code readable and maintainable.

    my_summarise5 <- function (data, mean_var) {
      mean_name <- paste0("mean_", mean_var)
      plus_one_name <- paste0(mean_name, "_plus_one")
    
      data[[mean_name]] <- mean(data[[mean_var]])
      data[[plus_one_name]] <- data[[mean_name]] + 1
    
      data
    }
    

    Anybody who knows R can understand the above.

    tmp <- data.frame(a = 1:5)
    my_summarise5(tmp, "a")
    ##   a mean_a mean_a_plus_one
    ## 1 1      3               4
    ## 2 2      3               4
    ## 3 3      3               4
    ## 4 4      3               4
    ## 5 5      3               4
    
    

    If you want to pass a bare symbol as mean_var, then just add this line to the start of the function:

    mean_var <- as.character(substitute(mean_var))
    

    This isn't perfect, because it'll break with deeply nested functions. So you could mix a little tidyverse in by doing (something like) mean_var <- enquo(mean_var). But I still would prefer the simple data manipulation to stuff with mutate and across.