为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

手掌心 2019-11-30 10:38:25

我想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


查看完整描述

3 回答

?
芜湖不芜

对于编程,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已被使用%.%,这是上面最初使用的内容,但现在%>%受到青睐,因此在上面进行了更改,以保持相关性。


现在不建议使用Update 2重新分组,而应使用group_by_。


根据Roberto的评论,Update 3group_by_(list(...))现在成为group_by_(...)dplyr的新版本。


更新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)


查看完整回答
反对 2019-11-30
?
慕哥9229398

从dplyr 0.7.0开始,您可以使用tidy eval完成此操作。


有关更多详细信息,请参见http://dplyr.tidyverse.org/articles/programming.html。


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


查看完整回答
反对 2019-11-30
?
繁星coding

他们来的时候很丑,但她的工作是:


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())


查看完整回答
反对 2019-11-30
  • 3 回答
  • 0 关注
  • 173 浏览

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信