Reputation: 351
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
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
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