How to pass a dynamic column name in a pipe in custom function in R
Asked Answered
M

2

7

I've created a dynamic column name w/ dplyr::mutate() based on this thread Use dynamic variable names in `dplyr` and now I want to sort the new column.... but I'm not correctly passing the column name

library(glue)
library(dplyr)

# data
set.seed(123)
df <- data.frame(distance = sample(1:100, size = 10))

# custom function
multiply_function <- function(df, metric, multiplier){
  
  df %>% 
    mutate(., "{{metric}}_x{{multiplier}}" := {{metric}} * multiplier) %>% 
    arrange(desc("{{metric}}_x{{multiplier}}")) # <--- this is not working
}

df %>% 
  multiply_function(., metric = distance, multiplier = 3)

   distance distance_x3
1        31          93
2        79         237
3        51         153
4        14          42
5        67         201
6        42         126
7        50         150
8        43         129
9        97         291
10       25          75
Million answered 7/2, 2022 at 7:23 Comment(0)
P
5

Unfortunately I don't know if any way to use that nice glue syntax with anything that's not on the left side of a :=. That's there the magic happens. You can get something to work if you take care of the explicity conversion to sumbol your self and do the string building manually. It's not pretty, but this works

multiply_function <- function(df, metric, multiplier){
  metric <- ensym(metric)
  newname <- glue::glue("{rlang::as_string(metric)}_x{as.character(multiplier)}")
  df %>% 
    mutate("{newname}" := !!metric * multiplier) %>% 
    arrange(desc(.data[[newname]]))
}
Psychotechnics answered 7/2, 2022 at 7:47 Comment(2)
How would I modify this if I wanted to pass metric and multiplier as lists so I could loop thru each?Million
I created a new question here: #71084091Million
S
2

I'm not sure this arranging step is best placed within a function if that function is part of a pipe itself. Problems may emerge if trying to make several variables. For one new variable:

multiply_function <- function(df, metric, multiplier){
  df %>% 
    mutate("{{metric}}_x{{multiplier}}" := {{metric}} * multiplier) %>%
    arrange(desc(!!rlang::sym(setdiff(names(.), names(df)))))
}
Storey answered 7/2, 2022 at 8:3 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.