Parseltongue
Parseltongue

Reputation: 11707

Dynamically construct variable names in mutate in dplyr via a function

I'd like to make a function in which I can supply a dataset and a list of prefixes. It uses those prefixes to construct columns that involve the use of those prefixes, and returns the final dataset, like so:

data <- data.frame(demo1_a = 3,demo1_b = 5, demo2_a = 4,demo2_b = 5)
make_vars(data, prefixes = list('demo1', 'demo2'))

make_vars <- function(data, prefixes){
  for(i in prefixes){
    data = data %>% 
      mutate({i}_subtraction = {i}_a - {i}_b,
             {i}_addition = {i}_a + {i}_b,
    )
  }
 return(data)
}

The result data.frame would look like:

  demo1_a demo1_b demo2_a demo2_b demo1_subtraction demo1_addition demo2_addition demo2_subtraction
1       3       5       4       5                -2              8              9                -1

I see in this answer: https://stackoverflow.com/a/59224230/372526, they reference curly-curly operators ({{}}) in rlang which allows you to reference a variable name dynamically, but I haven't found how to "paste" other suffixes like "_subtraction" and "_b" to that through a function.

Upvotes: 0

Views: 121

Answers (1)

Bruno
Bruno

Reputation: 4150

Here is my proposed solution

library(tidyverse)
data <- data.frame(a = 1, b = 2, demo1_a = 3,demo1_b = 5, demo2_a = 4,demo2_b = 5)


my_mutate <- function(df, name) {
  name_a <- paste0(name,"_a")
  name_b <- paste0(name,"_b")

  name_add <- paste0(name,"_addition")
  name_sub <- paste0(name,"_subtraction")

  df %>% 
    mutate(!! name_add := !! rlang::parse_expr(name_a) + !! rlang::parse_expr(name_a),
           !! name_sub := !! rlang::parse_expr(name_a) - !! rlang::parse_expr(name_a))


}


data %>% 
  my_mutate("demo1") %>% 
  my_mutate("demo2")

If you need to pass a list of names

vector_names <- c("demo1","demo2")

loop_mutate <- function(df, vector_names) {
  for (i in vector_names) {
    df <- df %>% my_mutate(i)
  }
  df
} 

loop_mutate(data,vector_names = vector_names)

Upvotes: 1

Related Questions