当前位置: 首页 > 知识库问答 >
问题:

dplyr:如何在函数中使用group_ by?

长孙章横
2023-03-14

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

乐正德华
2023-03-14
匿名用户

作为对@G .格罗滕迪克的回答中更新6的补充,如果你想在你的总结函数中使用一个字符串作为参数,而不是用双括号(< code>{{)包含参数,你应该使用< code >。数据代名词,如编程简介:在多个变量上循环中所述:

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

颛孙铭
2023-03-14

更新:从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
龙晟睿
2023-03-14

对于编程而言,group_

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 regroup现在已被否决,请改用group_by_代替。

根据Roberto的评论,更新3<code>group_ by_。

更新 4 添加了注释中建议的次要更改。

更新5:使用rlang/tidyeval,现在可以做到这一点:

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

或传递物种未评估,即周围没有引号:

library(rlang)
mytable <- function(x, ...) {
  group_ <- enquos(...)
  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)

 类似资料:
  • 我有一个接受NSE参数的函数。 假设我有一个tibble,其中有一列需要订购。我想创建一个函数,它可以根据函数参数中输入的名称对列名进行排序。但是,如果我不使用参数,我希望它不对列进行排序,因此我使用< code>column_name = NULL作为默认参数(或< code>column_name = NA) 创建于 2022-04-11 由 reprex 软件包 (v2.0.1) 然而,尽管

  • 我有以下数据集“df1”: 我使用“group_by”和“总结”根据“类”列的最小值对codfam进行分组 它工作正常,并返回如下结果: 现在,我将获得与函数“summarize”保留在数据集中的每个codfam相关的列“sex”的值,如下所示: 我试着用 但不幸的是,它不起作用。 任何帮助或建议将不胜感激,提前感谢!

  • 我试图计算在一个Tibble中源向量和比较向量之间的Jaccard相似度。 jaccard_sim中的所有值都为零。但是,如果我们运行类似这样的东西,我们得到第一个条目的正确的Jaccard相似度为0.2:

  • 我想使用dplyr的mutate_at函数将一个函数应用于数据帧中的几个列,其中该函数输入它直接应用到的列以及数据帧中的另一列。 作为一个具体的例子,我希望改变以下数据帧 与调用类似 返回一个看起来像这样的数据框 所需的调用将类似于以下对的调用: 我知道这可以通过几种方式在base R中实现,但为了可读性、与数据库的接口等,我特别希望使用dplyr的mutate\u at函数来实现这一目标。 在d

  • 我目前正在阅读React官方网站,在那里我遇到了这个问题。React官方网站声明我们可以在JSX中使用函数代码。因此,我尝试了以下代码,但不起作用。 ABCD类扩展了React。组件{ } 我知道,我知道,你们中的一些人可能会说,看看React网站上给出的例子。我看到了,官网上的例子涉及到外部功能。我只是想知道我们能否独立使用JSX内部的函数。 有关更多信息,请参阅此链接:https://reac

  • 我编写了这个函数,它只是用子字符串替换数据表列中的每个值: 但每次我试着运行它时,我都会发现错误: 现在我已经做了很多关于为什么它不起作用的研究,但我不明白。我读过一些关于标准评估和懒散的东西,但我尝试的似乎都不管用。有什么帮助吗? 谢谢