Search code examples
rfunctionrenametidyeval

Passing a column name for a new column in a function without tidyeval?


I have worked a solution to this problem with tidyeval, is there a base R method?

library(dplyr)

new_col <- function(df, col_name, col_vals){
  df |>
    cbind(temp_name = col_vals) |>
    rename({{col_name}} := temp_name)
}

sleep %>% 
  new_col(sample, "sample1") |>
  new_col(condition, "condition2") |>
  head()
#>   extra group ID  sample  condition
#> 1   0.7     1  1 sample1 condition2
#> 2  -1.6     1  2 sample1 condition2
#> 3  -0.2     1  3 sample1 condition2
#> 4  -1.2     1  4 sample1 condition2
#> 5  -0.1     1  5 sample1 condition2
#> 6   3.4     1  6 sample1 condition2

Created on 2022-06-24 by the reprex package (v2.0.1)

This seems indirect and depends on tidyeval concepts that are less known. This answer also uses {{}} and this answer uses enquo(). My solution also needs :=.

Ideally, I want to map vectors of metadata (say, in a dataframe) to a matching list of dataframes/objects.


Solution

  • In base R, we can use deparse/substitute

    new_col <- function(df, col_name, col_vals){
      cn <- deparse(substitute(col_name))
      df[[cn]] <- col_vals  
       df
    }
    

    -testing

     sleep %>% 
    +   new_col(sample, "sample1") |>
    +   new_col(condition, "condition2") |>
    +   head()
      extra group ID  sample  condition
    1   0.7     1  1 sample1 condition2
    2  -1.6     1  2 sample1 condition2
    3  -0.2     1  3 sample1 condition2
    4  -1.2     1  4 sample1 condition2
    5  -0.1     1  5 sample1 condition2
    6   3.4     1  6 sample1 condition2