13

So I'm trying to do some programming in dplyr and I am having some trouble with the enquo and !! evaluations.

Basically I would like to mutate a column to a dynamic column name, and then be able to further manipulate that column (i.e. summarize). For instance:

my_function <- function(data, column) {

  quo_column <- enquo(column)

  new_col <- paste0(quo_column, "_adjusted")[2]

  data %>%
     mutate(!!new_col := (!!quo_column) + 1) 
  }

my_function(iris, Petal.Length)

This works great and returns a column called "Petal.Length.adjusted" which is just Petal.Length increased by one.

However I can't seem to summarize this new column.

my_function <- function(data, column) {

  quo_column <- enquo(column)

   new_col <- paste0(quo_column, "_adjusted")[2]

   mean_col <- paste0(quo_column, "_meanAdjusted")[2]

   data %>%
      mutate(!!new_col := (!!quo_column) + 1) %>%
      group_by(Species) %>%
      summarize(!!mean_col := mean(!!new_col))
}

my_function(iris, Petal.Length)

This results in a warning stating the argument "Petal.Length_adjusted" is not numeric or logical, although the output from the mutate call gives a numeric column.

How do I reference this dynamically generated column name to pass it in further dplyr functions?

John Harley
  • 156
  • 1
  • 6

1 Answers1

16

Unlike the quo_column which is a quosure, the new_col and mean_col are strings, so we convert it to symbol using sym (from rlang) and then do the evaluation

my_function <- function(data, column) {

   quo_column <- enquo(column)

   new_col <- paste0(quo_column, "_adjusted")[2]       

   mean_col <- paste0(quo_column, "_meanAdjusted")[2]

   data %>%
      mutate(!!new_col := (!!quo_column) + 1)  %>%
      group_by(Species) %>%
      summarise(!!mean_col := mean(!! rlang::sym(new_col)))
}

head(my_function(iris, Petal.Length))
# A tibble: 3 x 2
#  Species    Petal.Length_meanAdjusted
#  <fct>                          <dbl>
#1 setosa                          2.46
#2 versicolor                      5.26
#3 virginica                       6.55
Tung
  • 26,371
  • 7
  • 91
  • 115
akrun
  • 874,273
  • 37
  • 540
  • 662