【问题标题】:Non standard evaluation in dplyr: how do you indirect a function's multiple arguments? [duplicate]dplyr 中的非标准评估:如何间接调用函数的多个参数? [复制]
【发布时间】:2021-08-23 00:35:38
【问题描述】:

我正在尝试编写一个函数,该函数可以将一个或多个参数作为变量传递给 dplyr 函数。我想了解一般情况下如何做到这一点。 Programming with dplyr 似乎没有涵盖该问题,并且您可以在 Google 或小插图中找到的一些更具权威性的文档(即 ?`!!!`)似乎已经过时。下面我提供了一个示例,说明我想要得到什么以及我失败的地方:

df <- as_tibble(mtcars)


df %>% group_by(cyl, gear) %>% summarise(mpg = mean(mpg)) #This is the result I want from a function


testfunc <- function(variables) {
  df %>% group_by({{variables}}) %>% summarise(mpg = mean(mpg))
}

testfunc(cyl)                                             #It works for a single variable

testfunc(cyl, gear)                                       #It fails for multiple variables

testfunc2 <- function(variables) {                        #Second attempt
  variables <- enquos(variables)
  df %>% group_by(!!variables) %>% summarise(mpg = mean(mpg))
}

testfunc2(cyl, gear)                                       #Unused argument error
testfunc2(c(cyl, gear))                                    #Doesn't work
testfunc2(c("cyl", "gear"))                                #Doesn't work

一般来说,你是如何解决这个问题的?

谢谢!!

【问题讨论】:

  • 您提供的链接确实涵盖了这一点。使用testfunc &lt;- function(...) {df %&gt;% group_by(...) %&gt;% summarise(mpg = mean(mpg))}。但是您需要决定如何传递变量。您不能期望字符值和符号的工作方式相同。您不能将字符值直接传递给group_by
  • 谢谢,你说得对,我错过了,就是这样。

标签: r dplyr nse


【解决方案1】:

您可以为 data.frame 定义一个 arg 并将其他变量的 ... 添加到 group by

testfunc <- function(df,...) {
  df %>%
    group_by(...) %>%
    summarise(mpg = mean(mpg))
}
testfunc(mtcars,cyl,gear)  

【讨论】:

    【解决方案2】:

    这在 Hadley Wickham (https://adv-r.hadley.nz/ / https://amzn.to/2WoabjB) 编写的“Advanced R”中有详细介绍,例如第 6、19、20 章:

    library(tidyverse)
    df <- as_tibble(mtcars)
    df %>% group_by(cyl, gear) %>% summarise(mpg = mean(mpg))
    #> `summarise()` has grouped output by 'cyl'. You can override using the `.groups` argument.
    #> # A tibble: 8 x 3
    #> # Groups:   cyl [3]
    #>     cyl  gear   mpg
    #>   <dbl> <dbl> <dbl>
    #> 1     4     3  21.5
    #> 2     4     4  26.9
    #> 3     4     5  28.2
    #> 4     6     3  19.8
    #> 5     6     4  19.8
    #> 6     6     5  19.7
    #> 7     8     3  15.0
    #> 8     8     5  15.4
    
    testfunc <- function(variables) {
      df %>% group_by({{variables}}) %>% summarise(mpg = mean(mpg))
    }
    
    testfunc(cyl)
    #> # A tibble: 3 x 2
    #>     cyl   mpg
    #>   <dbl> <dbl>
    #> 1     4  26.7
    #> 2     6  19.7
    #> 3     8  15.1
    testfunc(cyl, gear)
    #> Error in testfunc(cyl, gear): unused argument (gear)
    
    # https://adv-r.hadley.nz/functions.html?q=...#fun-dot-dot-dot
    testfunc2 <- function(variables, ...) {                        #Second attempt
      variables <- enquos(variables, ...)
      df %>% group_by(!!!variables) %>% summarise(mpg = mean(mpg))
    }
    
    testfunc2(cyl, gear)
    #> `summarise()` has grouped output by 'cyl'. You can override using the `.groups` argument.
    #> # A tibble: 8 x 3
    #> # Groups:   cyl [3]
    #>     cyl  gear   mpg
    #>   <dbl> <dbl> <dbl>
    #> 1     4     3  21.5
    #> 2     4     4  26.9
    #> 3     4     5  28.2
    #> 4     6     3  19.8
    #> 5     6     4  19.8
    #> 6     6     5  19.7
    #> 7     8     3  15.0
    #> 8     8     5  15.4
    

    reprex package (v2.0.0) 于 2021 年 8 月 23 日创建

    【讨论】:

      猜你喜欢
      • 2020-04-15
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      相关资源
      最近更新 更多