dplyr:如何在函数内部使用group_?

dplyr:如何在函数内部使用group_?,r,dplyr,tidyeval,nse,R,Dplyr,Tidyeval,Nse,我想在另一个函数中使用dplyr::group_by函数,但我不知道如何将参数传递给此函数 有人能提供一个有效的例子吗 library(dplyr) data(iris) iris %.% group_by(Species) %.% summarise(n = n()) # ## Source: local data frame [3 x 2] ## Species n ## 1 virginica 50 ## 2 versicolor 50 ## 3 setosa 50

我想在另一个函数中使用
dplyr::group_by
函数,但我不知道如何将参数传递给此函数

有人能提供一个有效的例子吗

library(dplyr)
data(iris)
iris %.% group_by(Species) %.% summarise(n = n()) # 
## Source: local data frame [3 x 2]
##      Species  n
## 1  virginica 50
## 2 versicolor 50
## 3     setosa 50

mytable0 <- function(x, ...) x %.% group_by(...) %.% summarise(n = n())
mytable0(iris, "Species") # OK
## Source: local data frame [3 x 2]
##      Species  n
## 1  virginica 50
## 2 versicolor 50
## 3     setosa 50

mytable1 <- function(x, key) x %.% group_by(as.name(key)) %.% summarise(n = n())
mytable1(iris, "Species") # Wrong!
# Error: unsupported type for column 'as.name(key)' (SYMSXP)

mytable2 <- function(x, key) x %.% group_by(key) %.% summarise(n = n())
mytable2(iris, "Species") # Wrong!
# Error: index out of bounds
库(dplyr)
数据(iris)
虹膜%。%按(物种)分组%。%总结(n=n())#
##来源:本地数据帧[3 x 2]
##物种n
##1弗吉尼亚州50
##2彩色50
##3刚毛50

mytable0虽然很难看,但她工作:

mytable3 <- function(x, key) {
  my.call <- bquote(summarise(group_by(.(substitute(x)), NULL), n = n()))
  my.call[[2]][[3]] <- as.name(key)
  eval(my.call, parent.frame())
} 
mytable3(iris, "Species")
# Source: local data frame [3 x 2]
#
#      Species  n
# 1  virginica 50
# 2 versicolor 50
# 3     setosa 50

mytable3对于编程,
groupby
groupby
相对应:

library(dplyr)

mytable <- function(x, ...) x %>% group_by_(...) %>% summarise(n = n())
mytable(iris, "Species")
# or iris %>% mytable("Species")
更新在编写本文件时,dplyr使用了
%.%
,这是上面最初使用的内容,但现在有人喜欢使用
%>%
,因此我们在上面对其进行了更改,以保持其相关性

更新2重新分组现在已被弃用,请改用分组方式

更新3
分组依据(列表(…)
根据Roberto的评论,现在在新版本的dplyr中成为
分组依据(…)

更新4在评论中添加了建议的微小变化

更新5:使用rlang/tidyeval,现在可以执行以下操作:

library(rlang)
mytable <- function(x, ...) {
  group_ <- syms(...)
  x %>% 
    group_by(!!!group_) %>% 
    summarise(n = n())
}
mytable(iris, "Species")
更新6:如果只有一个分组变量,则现在有一个{…}符号:

mytable <- function(x, group) {
  x %>% 
    group_by({{group}}) %>% 
    summarise(n = n())
}
mytable(iris, Species)
mytable%
分组依据({{group}})%>%
总结(n=n())
}
mytable(鸢尾属,物种)

更新:从dplyr 0.7.0开始,您可以使用tidy eval来完成此操作

有关更多详细信息,请参阅

library(tidyverse)
data("iris")

my_table <- function(df, group_var) {
  group_var <- enquo(group_var)      # Create quosure
  df %>% 
    group_by(!!group_var) %>%        # Use !! to unquote the quosure
    summarise(n = n())
}

my_table(iris, Species)

> my_table(iris, Species)
# A tibble: 3 x 2
     Species     n
      <fctr> <int>
1     setosa    50
2 versicolor    50
3  virginica    50
库(tidyverse)
数据(“iris”)
我的桌子%#使用!!取消报价
总结(n=n())
}
my_表(鸢尾,物种)
>my_表(鸢尾,物种)
#一个tibble:3x2
物种n
1刚毛50
2彩色50
3弗吉尼亚州50

作为@G.Grothendieck中更新6的补充,如果您想在摘要函数中使用字符串作为参数,而不是使用双大括号(
{
)包含参数,则应使用
.data
代词,如以下所述:

mytable%
分组依据(.data[[group]])%>%
总结(n=n())
}

组字符串不需要使用
as.name
mytable谢谢。已将
as.name(key)
替换为
。现在,在dplyr 0.3中使用lazyeval更简单:
mytable%group\u by_u(…)%%摘要(n=n())
@Roberto的解决方案可以用magrittr的功能序列概念重新表述:使用
mytable%group\u by_u(…)%%>%summary(n=n())
mytable(“物种”)
给出一个功能序列,因此
iris%>%mytable(“物种”)
给出了所需的摘要。(注意调用
()
是必要的-一个小的“疣”)当然,这个额外的解耦程度是否值得取决于具体的应用。复制这个的可能重复,
iris%。%groupby(Species)%。%summary(n=n())
导致
n()中的错误:不应直接调用此函数。
。WTF?!dplyr 0.1.2,R 3.0.3^这是由于错误地先加载dplyr,然后加载plyr,导致基本FN(如
变异、汇总、排列、描述等)被屏蔽而导致的已知问题。请参阅相关:不正确()检查时给你留个便条吗?嗨@Elin。我不太清楚你的意思。我只是重新运行了这段代码,没有看到任何便条。在包生成检查中?我看到了。我没有尝试将其包含在包中。仅使用dply::n()是否解决了便条?不。我想你可能需要引用,然后取消引用整个表达式。
library(rlang)
mytable <- function(x, ...) {
  group_ <- enquos(...)
  x %>% 
    group_by(!!!group_) %>% 
    summarise(n = n())
}
mytable(iris, Species)
mytable <- function(x, group) {
  x %>% 
    group_by({{group}}) %>% 
    summarise(n = n())
}
mytable(iris, Species)
library(tidyverse)
data("iris")

my_table <- function(df, group_var) {
  group_var <- enquo(group_var)      # Create quosure
  df %>% 
    group_by(!!group_var) %>%        # Use !! to unquote the quosure
    summarise(n = n())
}

my_table(iris, Species)

> my_table(iris, Species)
# A tibble: 3 x 2
     Species     n
      <fctr> <int>
1     setosa    50
2 versicolor    50
3  virginica    50
mytable <- function( x, group ) {
  x %>% 
    group_by( .data[[group]] ) %>% 
    summarise( n = n() )
}

group_string <- 'Species'

mytable( iris, group_string )

`summarise()` ungrouping output (override with `.groups` argument)
# A tibble: 3 x 2
  Species        n
  <fct>      <int>
1 setosa        50
2 versicolor    50
3 virginica     50