Search code examples
rdplyrrlangtidyeval

Create column from symbol in mutate (tidy eval)


So I want to create a new column called var that has the text "testing" for all rows. I.e. the result should be like mtcars$var <- "testing". I have tried different things such as as_name, as_string...

library(tidyverse)    
f <- function(df, hello = testing){


  df %>% 
    mutate(var = hello)
}

f(mtcars)

Solution

  • We can do:

    f <- function(df, hello = testing){
      hello <- deparse(substitute(hello))
      df %>% 
        mutate(var =rlang::as_name(hello))
    }
    
    f(mtcars)
    

    However, as pointed out by @Lionel Henry(see comments below):

    deparse will not check for simple inputs and might return a character vector. Then as_name() will fail if a length > 1 vector, or do nothing otherwise since it's already a string

    as_name(substitute(hello)) does the same but checks the input is a simple symbol or string. It is more constrained than as_label()

    It might therefore be better rewritten as:

    f <- function(df, hello = testing){
      hello <- as_label(substitute(hello))
      df %>% 
        mutate(var = hello )
    }
    

    Or:

    f <- function(df, hello = testing){
      hello <- rlang::as_name(substitute(hello))
      df %>% 
        mutate(var = hello)
    }
    

    Result:

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb     var
    1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 testing
    2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 testing
    3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 testing