从dumr mutate计算输出列名

pzfprimi  于 2023-11-14  发布在  其他
关注(0)|答案(2)|浏览(101)

有没有一种方法可以从documentr mutate中提取输出列的名称?
我有一个使用dplyr::mutate()的函数,我希望能够在不使用transmute()的情况下提取已使用和/或新列的名称。

伪函数示例
my_function <- function(.data, ...){
  out <- mutate(.data, ...)
  
  ### Pseudo code to calculate output column names
  # out_names <- "code to calculate the used and new col names"
  
  out_names
}

字符串

用户输入示例

library(dplyr)
my_function(iris, Sepal.Length = as.integer(Sepal.Length),
               across(all_of("Sepal.Width"), \(x) x * 100),
               Petal.Width = Petal.Length,
               new_column = 42)

期望输出

c("Sepal.Length", "Sepal.Width", "Petal.Width", "new_column")


这样做的原因是我有一些经常调用mutate()的自定义函数,我需要使用这些输出名称进行进一步的转换。
任何帮助和建议将不胜感激。

bmp9r5qi

bmp9r5qi1#

如果计算自定义变量不是太昂贵,你可以负担得起这样做两次,那么我会简单地更改为transmute并拉取列名。这使得获取自定义函数中使用的所有列名变得超级容易。

library(tidyverse)

my_function <- function(.data, ...){
  out <- mutate(.data, ...)
  out_temp <- transmute(.data, ...)
  
  colnames(out_temp)
}

my_function(iris, Sepal.Length = as.integer(Sepal.Length),
               across(all_of("Sepal.Width"), \(x) x * 100),
               Petal.Width = Petal.Length,
               new_column = 42)
#> [1] "Sepal.Length" "Sepal.Width"  "Petal.Width"  "new_column"

字符串
正如你在注解中提到的,这个方法也适用于未命名的函数:

my_function(iris, rowSums(pick(1:2)))
#> [1] "rowSums(pick(1:2))"


当然,如果你只需要列的名字,而不需要实际计算mutate,那么你可以放弃原来的mutate,只使用transmute。

vsmadaxz

vsmadaxz2#

一种方法是捕获调用并1)提取命名的转换。2)across()调用,传递给tidyselect::eval_select(),以便可以提取“tidyselected”的变量名称。

my_function <- function(.data, ...) {
  fcall <- match.call()
  res <- as.list(fcall)[3:length(fcall)]
  named_vars <- names(res)[names(res) != ""]
  across_vars <- unlist(lapply(res[names(res) == ""], \(x) names(tidyselect::eval_select(x[[2]], .data))))
  out_names <- unique(unname(c(named_vars, across_vars)))
  
  # rest of your function
  out <- mutate(.data, ...)
  out_names[!out_names %in% names(formals(dplyr:::mutate.data.frame))
}

my_function(iris,
          Sepal.Length = as.integer(Sepal.Length),
          across(all_of("Sepal.Width"), \(x) x * 100),
          Petal.Width = Petal.Length,
          new_column = 42)

[1] "Sepal.Length" "Petal.Width"  "new_column"   "Sepal.Width"

字符串

相关问题