Return 包装函数中的变量名称为带有 dplyr 的字符串

Return variable name as string with dplyr in wrapper function

我认为这是一个相当简单的问题。我正在创建一个自定义函数,该函数执行一系列汇总统计并为某些报告一致地格式化数据。为此,我编写了一个 function(),它将 3 个变量作为输入、一个数据集、一个分组变量和一个感兴趣的响应变量。我使用 dplyr::summarize() 执行汇总统计。我知道要在自定义函数中使用 dplyr::summarize,我必须在 dplyr:: 函数中包含分组变量和带有卷曲符号的响应变量。我想在输出 tibble 中记录响应变量的名称。在非 tidyverse:: 世界中,我会使用 deparse(substitute()) 来完成此操作。不过,这个方法显然在tidyverse::内行不通。这是我的可重现示例。我将逐步完成它,然后 post 问题末尾的不间断代码。

第一次尝试时,我尝试了 deparse(substitute({{}})) 方法

library(tidyverse)
data("iris")

fxn1<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute({{var}})))
}

Demo1<-fxn1(iris, Species, Petal.Width)
Demo1

不幸的是,这在 Var 列中创建了某种表达式,并弄乱了摘要。

# A tibble: 12 x 3
# Groups:   Species [3]
   Species    Mean_Val Var                                                         
   <fct>         <dbl> <chr>                                                       
 1 setosa        0.246 "(function (...) "                                          
 2 setosa        0.246 "{"                                                         
 3 setosa        0.246 "    .External2(ffi_tilde_eval, sys.call(), environment(), ~
 4 setosa        0.246 "})(Petal.Width)"                                           
 5 versicolor    1.33  "(function (...) "                                          
 6 versicolor    1.33  "{"                                                         
 7 versicolor    1.33  "    .External2(ffi_tilde_eval, sys.call(), environment(), ~
 8 versicolor    1.33  "})(Petal.Width)"                                           
 9 virginica     2.03  "(function (...) "                                          
10 virginica     2.03  "{"                                                         
11 virginica     2.03  "    .External2(ffi_tilde_eval, sys.call(), environment(), ~
12 virginica     2.03  "})(Petal.Width)"   

第二次尝试,我摆脱了 deparse(substitute())

中的卷曲符号
fxn2<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute(var)))
}

Demo2<-fxn2(iris, Species, Petal.Width)
Demo2

这几乎是正确的,但它没有在 Var 列中输入“Petal.Width”,而是添加了“var”。

# A tibble: 3 x 3
  Species    Mean_Val Var  
  <fct>         <dbl> <chr>
1 setosa        0.246 var  
2 versicolor    1.33  var  
3 virginica     2.03  var  

我希望我的数据看起来像这样

Desired<-iris %>% group_by(Species) %>%  summarize(Mean_Val=mean(Petal.Width), Var="Petal.Width")
Desired

看起来像这样:

# A tibble: 3 x 3
  Species    Mean_Val Var        
  <fct>         <dbl> <chr>      
1 setosa        0.246 Petal.Width
2 versicolor    1.33  Petal.Width
3 virginica     2.03  Petal.Width

有谁知道如何让 dplyr::deparse(substitute) 等效,但实际上是 return 变量名称,而不是参数名称?任何指导将不胜感激。

这是不间断的可重现示例:

library(tidyverse)
data("iris")

fxn1<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute({{var}})))
}

Demo1<-fxn1(iris, Species, Petal.Width)
Demo1

fxn2<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute(var)))
}

Demo2<-fxn2(iris, Species, Petal.Width)
Demo2

Desired<-iris %>% group_by(Species) %>%  summarize(Mean_Val=mean(Petal.Width), Var="Petal.Width")
Desired

这种提供了您预期的输出(“Var”是一个列表,所以不理想);它能解决您的问题吗?

library(tidyverse)
data("iris")

fxn1<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute({{var}})))
}

Demo1<-fxn1(iris, Species, Petal.Width)
#> `summarise()` has grouped output by 'Species'. You can override using the
#> `.groups` argument.
Demo1
#> # A tibble: 12 × 3
#> # Groups:   Species [3]
#>    Species    Mean_Val Var                                                      
#>    <fct>         <dbl> <chr>                                                    
#>  1 setosa        0.246 "(function (...) "                                       
#>  2 setosa        0.246 "{"                                                      
#>  3 setosa        0.246 "    .External2(ffi_tilde_eval, sys.call(), environment(…
#>  4 setosa        0.246 "})(Petal.Width)"                                        
#>  5 versicolor    1.33  "(function (...) "                                       
#>  6 versicolor    1.33  "{"                                                      
#>  7 versicolor    1.33  "    .External2(ffi_tilde_eval, sys.call(), environment(…
#>  8 versicolor    1.33  "})(Petal.Width)"                                        
#>  9 virginica     2.03  "(function (...) "                                       
#> 10 virginica     2.03  "{"                                                      
#> 11 virginica     2.03  "    .External2(ffi_tilde_eval, sys.call(), environment(…
#> 12 virginica     2.03  "})(Petal.Width)"

fxn2<-function(DF, grp, var){
  out<-DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=deparse(substitute(var)))
}

Demo2<-fxn2(iris, Species, Petal.Width)
Demo2
#> # A tibble: 3 × 3
#>   Species    Mean_Val Var  
#>   <fct>         <dbl> <chr>
#> 1 setosa        0.246 var  
#> 2 versicolor    1.33  var  
#> 3 virginica     2.03  var

Desired<-iris %>% group_by(Species) %>%  summarize(Mean_Val=mean(Petal.Width), Var="Petal.Width")
Desired
#> # A tibble: 3 × 3
#>   Species    Mean_Val Var        
#>   <fct>         <dbl> <chr>      
#> 1 setosa        0.246 Petal.Width
#> 2 versicolor    1.33  Petal.Width
#> 3 virginica     2.03  Petal.Width

fxn3 <- function(DF, grp, var){
  DF %>% 
    group_by({{grp}}) %>% 
    summarize(Mean_Val=mean({{var}}, na.rm=TRUE),
              Var=c(ensym(var)))
}

Demo3 <- fxn3(iris, Species, Petal.Width)
Demo3
#> # A tibble: 3 × 3
#>   Species    Mean_Val Var   
#>   <fct>         <dbl> <list>
#> 1 setosa        0.246 <sym> 
#> 2 versicolor    1.33  <sym> 
#> 3 virginica     2.03  <sym>

print.data.frame(Demo3)
#>      Species Mean_Val         Var
#> 1     setosa    0.246 Petal.Width
#> 2 versicolor    1.326 Petal.Width
#> 3  virginica    2.026 Petal.Width

reprex package (v2.0.1)

创建于 2022-04-21