1

I have this dataframe:

vehicles <- tibble(vehicle = c("Car", "Car", "Motorbike"),
                   color = c("Red", "Black", "Blue"),
                   speed = c("Low", "High", "High"))
vehicle color speed
Car Red Low
Car Black High
Motorbike Blue High

I would like to create a new column that pastes the categorical values of columns that I choose based on a vector.

For instance, if I want to create a categorical column based on vehicle and color, I would do:

vehicles %>% mutate(category = paste(vehicle, color, sep = "_"))

Which would give me:

vehicle color speed category
Car Red Low Car_Red
Car Black High Car_Black
Motorbike Blue High Motorbike_Blue

However, I want to embed this code into a function, so that the columns to paste are determined by a character vector provided by the user.

E.g., user chooses choices = c("vehicle", "color", "speed"). But dplyr's tidy evaluation does not allow me to do vehicles %>% mutate(category = paste(choices, sep = "_")), because that would simply create a column vector full of "vehicle_color_speed" values. How would I then create something with the same result as:

vehicles %>% mutate(category = paste(vehicle, color, speed, sep = "_"))

but using the choices vector.

2 Answers2

2

With rlang::syms:

library(dplyr)
choices = c("vehicle", "color", "speed")
vehicles %>% 
  mutate(category = paste(!!!rlang::syms(choices), sep = "_"))

output

# A tibble: 3 × 4
  vehicle   color speed category           
  <chr>     <chr> <chr> <chr>              
1 Car       Red   Low   Car_Red_Low        
2 Car       Black High  Car_Black_High     
3 Motorbike Blue  High  Motorbike_Blue_High
Maël
  • 45,206
  • 3
  • 29
  • 67
  • It works, thanks! I see that rlang::syms returns a list of symbols based on the provided vector. However, what's the functionality of `!!!` in dplyr (inthis particular case)? Does it unpack the list for the expression? – Alberto Agudo Dominguez Nov 08 '22 at 09:48
  • 1
    Yes, kinda. It is similar to `do.call` in base R. Check [here](https://rlang.r-lib.org/reference/splice-operator.html) – Maël Nov 08 '22 at 09:53
0

Using unite

library(dplyr)
library(tidyr)
vehicles %>%
  unite(category, all_of(choices), remove = FALSE) %>%
  relocate(category, .after = last_col())

-output

# A tibble: 3 × 4
  vehicle   color speed category           
  <chr>     <chr> <chr> <chr>              
1 Car       Red   Low   Car_Red_Low        
2 Car       Black High  Car_Black_High     
3 Motorbike Blue  High  Motorbike_Blue_High
akrun
  • 874,273
  • 37
  • 540
  • 662