1

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.

tiptoebull
  • 161
  • 1
  • 8
  • NSE is less known. It you are using dplyr and implementing NSE, I would argue that tidyeval should then be used. That's the whole point. –  Jun 24 '22 at 15:54
  • Note that tidyverse functions generally use NSE for referring to _existing_ columns, not for creating new ones. – Lionel Henry Jun 24 '22 at 16:25

1 Answers1

1

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
akrun
  • 874,273
  • 37
  • 540
  • 662