Search code examples
rdplyrtidyeval

How to write use quos in a formula in R?


I am trying write a function which creates a new column by multiplying two other columns, with the names of all three columns being given as (string) parameters to the function.

I was thinking I could write something like this:

A <- data.frame(x = 1:5, y = 11:15)

f <- function(x, y, new) {
  x_quo <- rlang::enquo(x)
  y_quo <- rlang::enquo(y)
  new_quo <- rlang::enquo(new)
  A %<>% mutate (!!new_quo := !!x_quo * !!y_quo)
  A
}

f("x", "y", "new")

I was expecting this to be equivalent to running this code:

A <- data.frame(x = 1:5, y = 11:15)
A %<>% mutate (new = x * y);

However, but when I run that first code, I get this error:

 Error: Problem with `mutate()` input `new`.
 x non-numeric argument to binary operator
 i Input `new` is `"x" * "y"`.
 Run `rlang::last_error()` to see where the error occurred. 

What does this error mean? Is there a way to create a function like I've described?


Solution

  • Try to use sym and evaluate it with !!. I would also pass additional data argument to the function.

    library(dplyr)
    library(rlang)
    
    f <- function(data, x, y, new) {
      data %>% mutate (!!new := !!sym(x) * !!sym(y))
    }
    
    A %>% f("x", "y", "new")
    
    #  x  y new
    #1 1 11  11
    #2 2 12  24
    #3 3 13  39
    #4 4 14  56
    #5 5 15  75
    
    identical(A %>% f("x", "y", "new"), A %>% mutate (new = x * y))
    #[1] TRUE