Mas
Mas

Reputation: 351

Setting names intuitively with dplyr across() function

I want to manipulate several columns to create new columns with names that are variants of the names of the columns being manipulating.

dplyr 1.0.0's across() function seems like the tool for the job, but the .names argument seems to have limited functionality. Here's what I want to do:

tmp <- iris %>% 
  mutate(across(starts_with('Sepal'), 
                ~ .x - Petal.Length, 
                .names = gsub('Sepal', '', "{col}")))

but the gsub function doesn't work. I can work around this in the following way:

tmp <- iris %>% 
  mutate(across(starts_with('Sepal'), 
                ~ .x - Petal.Length, 
                .names = "mod_{col}"))

names(tmp) <- gsub("mod_Sepal", "mod_", names(tmp))

but that requires more code and is harder to keep track of. Am I missing something here and is there a simpler way to set the new column names with across?

Upvotes: 1

Views: 879

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388982

You can pass a function to .names as -

library(dplyr)

iris %>% 
  mutate(across(starts_with('Sepal'), ~ .x - Petal.Length, 
                .names = "{gsub('Sepal.', '', {col}, fixed = TRUE)}")) 

#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Length Width
#1          5.1         3.5          1.4         0.2  setosa    3.7   2.1
#2          4.9         3.0          1.4         0.2  setosa    3.5   1.6
#3          4.7         3.2          1.3         0.2  setosa    3.4   1.9
#4          4.6         3.1          1.5         0.2  setosa    3.1   1.6
#5          5.0         3.6          1.4         0.2  setosa    3.6   2.2
#6          5.4         3.9          1.7         0.4  setosa    3.7   2.2

Upvotes: 4

akrun
akrun

Reputation: 887108

We can use rename_at after the mutate step

library(dplyr)
library(stringr)
iris %>% 
  mutate(across(starts_with('Sepal'), 
            ~ .x - Petal.Length)) %>%      
  rename_at(vars(starts_with("Sepal")), ~ str_remove(., "Sepal"))

According to ?across

.names - The default (NULL) is equivalent to "{col}" for the single function case

And there is no option to remove the already existing column name, but, we can add a suffix or prefix

Upvotes: 4

Related Questions