dplyr:如何在函数中使用group_by?

时间:2014-02-16 17:52:14

标签: r dplyr

我想在另一个函数中使用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

4 个答案:

答案 0 :(得分:61)

对于编程,group_by_group_by的对应部分:

library(dplyr)

mytable <- function(x, ...) x %>% group_by_(...) %>% summarise(n = n())
mytable(iris, "Species")
# or iris %>% mytable("Species")

给出:

     Species  n
1     setosa 50
2 versicolor 50
3  virginica 50

更新在撰写本文时,dplyr使用的是%.%,这是上面最初使用的,但现在%>%受到青睐,所以已将上面的内容更改为保持相关性

更新2 重新组合现已弃用,请改用group_by_。

根据Roberto的评论,

更新3 group_by_(list(...))现在在新版本的dplyr中变为group_by_(...)

更新4 添加了评论中建议的细微差异。

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

library(rlang)
mytable <- function(x, ...) {
  group_ <- syms(...)
  x %>% 
    group_by(!!!group_) %>% 
    summarise(n = n())
}
mytable(iris, "Species")

或传递Species未评估,即没有引号:

library(rlang)
mytable <- function(x, ...) {
  group_ <- quos(...)
  x %>% 
    group_by(!!!group_) %>% 
    summarise(n = n())
}
mytable(iris, Species)

答案 1 :(得分:7)

UPDATE :从dplyr 0.7.0开始,您可以使用整洁的eval来完成此任务。

有关详细信息,请参阅http://dplyr.tidyverse.org/articles/programming.html

otp_1.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    //
                }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //
                if(editable.length()>0){
                    otp_1.clearFocus();
                    otp_2.requestFocus();
                    otp_2.setCursorVisible(true);
                }
            }
        });

        otp_2.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                //
                if(editable.length() > 0) {
                    otp_2.clearFocus();
                    otp_3.requestFocus();
                    otp_3.setCursorVisible(true);
                }
            }
        });

        otp_3.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                //
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if(editable.length() > 0) {
                    otp_3.clearFocus();
                    otp_4.requestFocus();
                    otp_4.setCursorVisible(true);
                }
            }
        });

答案 2 :(得分:2)

他们来的时候很难看,但她的工作:

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

几乎可以肯定会导致这种情况破裂,但你明白了。我认为你不能搞砸这个电话。另一件事确实有效,但更加丑陋的是:

mytable4 <- function(x, key) summarise(group_by(x, x[[key]]), n = n())

答案 3 :(得分:1)

作为对@G 的answer更新 6 的补充。 Grothendieck,如果你想在你的摘要函数中使用一个 string 作为参数,而不是用双大括号 ({{) 包含参数,你应该使用 .data 代词如Programming vignette: Loop over multiple variables中所述:

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