Convert a dplyr vars() element back to character

Viewed 88

Original data frame:

df <- data.frame(col1=c("A", "B"), col2=c("C", "D"), stringsAsFactors=F)
df
  col1 col2
1    A    C
2    B    D

Using dplyr mutate_at, let's say I would like to replace all values of column col2 with the name of the column, in order to get:

df <- data.frame(col1=c("A", "B"), col2=c("col2", "col2"), stringsAsFactors=F)
df
  col1 col2
1    A col2
2    B col2

Using the following for instance, triggers an error:

df %>%
dplyr::mutate_at("col2", function(x){x=rlang::as_string(x)})

Note: the point of this example is not to replace all values of column col2, but to know how to convert vars(col2) vector back to a character string "col2".

Similar thread: R dplyr mutate_at accessing colnames

1 Answers

In dplyr::mutate_at it is not possible to access to columns name (only its values will be used in the function call), but we could use dplyr::across() and dplyr::cur_column():

library(dplyr)

df <- data.frame(col1=c("A", "B"), col2=c("C", "D"), stringsAsFactors=F)

df %>% 
  mutate(across(col2, ~ cur_column()))
#>   col1 col2
#> 1    A col2
#> 2    B col2

Created on 2021-01-11 by the reprex package (v0.3.0)

Instead of across we can write a simple function that can use the names and values of a column (including tidyselect helpers):

library(tidyverse)
library(rlang)


create_vars <- function (.vars, .f)  {
  data <- dplyr::cur_data()
  vars <- rlang::enexpr(.vars)
  cols <- tidyselect::eval_select(vars, data)
  f <- rlang::as_function(.f)
  
  cols <- dplyr::select(data, dplyr::all_of(names(cols)))
  new_tibble(imap(cols, f), nrow = nrow(data))
}

df <- data.frame(col1=c("A", "B"), col2=c("C", "D"), stringsAsFactors=F)

df %>% mutate(create_vars(starts_with("col"), ~ paste(.y, .x)))
#>     col1   col2
#> 1 col1 A col2 C
#> 2 col1 B col2 D

Created on 2021-01-11 by the reprex package (v0.3.0)

Related