如何在 R 中的自定义函数中的管道中传递动态列名

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

我基于此线程 Use dynamic variable names in `dplyr` 创建了一个带有 dplyr::mutate() 的动态列名称,现在我想对新列进行排序....但我没有正确传递列名

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

不幸的是,我不知道是否有任何方法可以将这种漂亮的胶水语法与 := 左侧以外的任何内容一起使用。魔法就在那里发生了。如果您处理显式转换以对自己进行加法运算并手动构建字符串,则可以使某些东西起作用。这不是很漂亮,但这个作品

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]]))
}

如果函数是管道本身的一部分,我不确定这个安排步骤是否最好放在函数中。如果尝试制作多个变量,可能会出现问题。对于一个新变量:

multiply_function <- function(df, metric, multiplier){
  df %>% 
    mutate("{{metric}}_x{{multiplier}}" := {{metric}} * multiplier) %>%
    arrange(desc(!!rlang::sym(setdiff(names(.), names(df)))))
}