使用字符串作为输入的dplyr编程

ltskdhd1  于 2023-05-26  发布在  其他
关注(0)|答案(3)|浏览(122)

我想写一个函数,在里面使用dplyr,我提供变量名作为字符串。不幸的是,dplyr-s使用NSE使其变得相当复杂。从Programming with dplyr中,我得到以下示例

my_summarise <- function(df, var) {
  var <- enquo(var)

  df %>%
    group_by(!!var) %>%
    summarise(a = mean(a))
}

my_summarise(df, g1)

然而,我想写一个函数,而不是g1,我可以提供"g1",我无法理解如何做到这一点。

n8ghc7c1

n8ghc7c11#

dplyr >= 1.0

使用双括号和cross函数的组合:

my_summarise2 <- function(df, group_var) {
  df %>% group_by(across({{ group_var }})) %>% 
    summarise(mpg = mean(mpg))
}

my_summarise2(mtcars, "cyl")

# A tibble: 3 x 2
#    cyl   mpg
#  <dbl> <dbl>
# 1     4  26.7
# 2     6  19.7
# 3     8  15.1

# same result as above, passing cyl without quotes
my_summarise(mtcars, cyl)

dplyr < 1.0

据我所知,你可以使用as.namesym(来自rlang包-我不知道dplyr最终是否会导入它):

library(dplyr)
my_summarise <- function(df, var) {
  var <- rlang::sym(var)
  df %>%
    group_by(!!var) %>%
    summarise(mpg = mean(mpg))
}

my_summarise <- function(df, var) {
  var <- as.name(var)
  df %>%
    group_by(!!var) %>%
    summarise(mpg = mean(mpg))
}

my_summarise(mtcars, "cyl")
# # A tibble: 3 × 2
#     cyl      mpg
#   <dbl>    <dbl>
# 1     4 26.66364
# 2     6 19.74286
# 3     8 15.10000
yi0zb3m4

yi0zb3m42#

使用rlang中的.data代词是另一个直接处理存储为字符串的列名的选项。
带有.data的函数如下所示

my_summarise <- function(df, var) {
     df %>%
          group_by(.data[[var]]) %>%
          summarise(mpg = mean(mpg))
}

my_summarise(mtcars, "cyl")
# A tibble: 3 x 2
    cyl   mpg
  <dbl> <dbl>
1     4  26.7
2     6  19.7
3     8  15.1
f0ofjuux

f0ofjuux3#

这是如何使用dplyr和来自base R的非常有用的as.name函数来实现的:

my_summarise <- function(df, var) {
  varName <- as.name(var)
  enquo_varName <- enquo(varName)

  df %>%
    group_by(!!enquo_varName) %>%
    summarise(a = mean(a))
}

my_summarise(df, "g1")

基本上,我们使用as.name()生成一个匹配var的name对象(这里var是一个字符串)。然后,在Programming with dplyr之后,我们使用enquo()来查看该名称并将关联值作为quosure返回。然后可以使用!!group_by()调用中取消对该引号的引用。

相关问题