Search code examples
rdplyrtidyeval

dplyr: Standard evaluation and enquo()


I heard standard evaluation is not recommended in dplyr, and we can do similar thing with enquo() and quo().

My original code (simplified) is

my_function <- function(data, x="OriginalX", y="OriginalY"){
  data %>%
     mutate_(CopyX = x, CopyY = y)
}

and it works.

I tried following code

my_function <- function(data, x="OriginalX", y="OriginalY"){
  qx <- enquo(x)
  qy <- enquo(y)
  data %>%
     mutate(CopyX = (!!qx), CopyY = (!!qy))
}

Why it does not work? And should we keep using standard evaluation?


Solution

  • The idea behind tidyeval is specifically that you don't need to put your column name between "". So this should work:

    my_function <- function(data, x= OriginalX , y= OriginalY ){
      qx <- enquo(x)
      qy <- enquo(y)
      data %>%
        mutate(CopyX = !!qx,
               CopyY = !!qy)
    }
    

    Note that the !!qx and !!qy don't need to be between parenthesis

    my_function(iris, Sepal.Length, Species) %>%
      head()
      Sepal.Length Sepal.Width Petal.Length Petal.Width Species CopyX  CopyY
    1          5.1         3.5          1.4         0.2  setosa   5.1 setosa
    2          4.9         3.0          1.4         0.2  setosa   4.9 setosa
    3          4.7         3.2          1.3         0.2  setosa   4.7 setosa
    4          4.6         3.1          1.5         0.2  setosa   4.6 setosa
    5          5.0         3.6          1.4         0.2  setosa   5.0 setosa
    6          5.4         3.9          1.7         0.4  setosa   5.4 setosa
    

    If you need to use strings in the function parameters, you can use the ensym function to convert them:

    my_function <- function(data, x= "OriginalX" , y= "OriginalY" ){
      qx <- ensym(x)
      qy <- ensym(y)
      data %>%
        mutate(CopyX = !!qx,
               CopyY = !!qy)
    }
    
    my_function(iris, "Sepal.Length", "Species") %>%
      head()
      Sepal.Length Sepal.Width Petal.Length Petal.Width Species CopyX  CopyY
    1          5.1         3.5          1.4         0.2  setosa   5.1 setosa
    2          4.9         3.0          1.4         0.2  setosa   4.9 setosa
    3          4.7         3.2          1.3         0.2  setosa   4.7 setosa
    4          4.6         3.1          1.5         0.2  setosa   4.6 setosa
    5          5.0         3.6          1.4         0.2  setosa   5.0 setosa
    6          5.4         3.9          1.7         0.4  setosa   5.4 setosa