【问题标题】:how to pass a column name to a function如何将列名传递给函数
【发布时间】:2018-11-19 03:42:09
【问题描述】:

我编写了一个函数来进行一些分析,包括使用NPS package 计算一个称为“净推荐值”的度量。

library(dplyr)
library(tidyr)
library(NPS)
df<-data.frame(score = sample(c(0:10),15,replace=TRUE),
           variable = sample(c('A', 'B', 'C'),15,replace=TRUE)
)
analyzer <- function(df,var, sco){
    df %>% group_by_(var) %>% transmute(n= nps(sco)) %>% unique()
}
analyzer(df,'variable','score')

这将为所有级别的变量返回NA

现在 dplyr 函数有一种方法可以处理 x 作为字符传递给它们(即,我在这里使用的 _ 版本),但 nps 函数没有。我还尝试将分数列传递为nps(.[[score]]),但这会返回整个列的 NPS,并且不会按 group_by 级别对其进行分解。

【问题讨论】:

    标签: r function dplyr rlang


    【解决方案1】:

    您可以使用 rlang 包,然后使用 !! 引用您的变量

    library(dplyr)
    library(tidyr)
    library(NPS)
    library(rlang)
    
    df<-data.frame(score = sample(c(0:10),15,replace=TRUE),
               variable = sample(c('A', 'B', 'C'),15,replace=TRUE)
    )
    analyzer <- function(df,var, sco){
        var <- rlang::enquo(var)
        sco <- rlang::enquo(sco)
        df %>% group_by(!!var) %>% transmute(n= nps(!!sco)) %>% unique()
    }
    analyzer(df, variable,score)
    

    【讨论】:

    • enquo 现在由 dplyr 重新导出,因此您无需使用 library 加载 rlang 或使用 :: 表示法;只需 enquo(var) 即可。
    • 第一个enquo 应该是ensym,因为您想强制用户提供单个符号进行分组,而不是任意表达式。正如它目前所写的那样,analyzer( df, variable*2, score ) 会给你一个模糊的(可能是意想不到的)结果,而ensym 会正确地抛出一个错误。 (当然,我很挑剔。否则这是一个很好的答案。)
    【解决方案2】:

    这是因为函数的输入没有得到正确的评估-

    (注意这里的实现方式,不管你输入一个裸表达式x = x还是一个字符x = "x",这个函数都会起作用)

    library(dplyr)
    library(tidyr)
    library(NPS)
    set.seed(123)
    
    # data
    df <- data.frame(score = sample(c(0:10), 15, replace = TRUE),
                     variable = sample(c('A', 'B', 'C'), 15, replace = TRUE))
    
    # custom function
    analyzer <- function(df, var, sco) {
      var <- rlang::ensym(var)
      sco <- rlang::ensym(sco)
    
      df <- df %>% 
        group_by(., !!rlang::enquo(var)) %>% 
        transmute(., n = NPS::nps(!!rlang::enquo(sco))) %>% 
        unique()
    
      return(df)
    }
    
    # using function
    analyzer(df, 'variable', 'score')
    #> # A tibble: 3 x 2
    #> # Groups:   variable [3]
    #>   variable      n
    #>   <fct>     <dbl>
    #> 1 C        -0.333
    #> 2 A        -0.4  
    #> 3 B        -0.25
    

    reprex package (v0.2.1) 于 2018 年 11 月 18 日创建

    【讨论】:

    • 不错!这适用于裸列名和列名作为字符串。
    猜你喜欢
    • 2017-09-12
    • 2017-04-15
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多