以编程方式在dplyr中删除`group_by`字段 [英] Programmatically dropping a `group_by` field in dplyr

查看:120
本文介绍了以编程方式在dplyr中删除`group_by`字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写将 data.frame 接受的函数,然后执行一些操作。我需要从 group_by 标准中添加和减去项目,才能到达想要去的地方。

I'm writing functions that take in a data.frame and then do some operations. I need to add and subtract items from the group_by criteria in order to get where I want to go.

如果我想向df添加 group_by 条件,那很简单:

If I want to add a group_by criteria to a df, that's pretty easy:

library(tidyverse)
set.seed(42)
n <- 10
input <- data.frame(a = 'a', 
                    b = 'b' , 
                    vals = 1
)

input %>%
  group_by(a) -> 
grouped 

grouped
#> # A tibble: 1 x 3
#> # Groups:   a [1]
#>   a     b      vals
#>   <fct> <fct> <dbl>
#> 1 a     b        1.

## add a group:
grouped %>% 
  group_by(b, add=TRUE)
#> # A tibble: 1 x 3
#> # Groups:   a, b [1]
#>   a     b      vals
#>   <fct> <fct> <dbl>
#> 1 a     b        1.

## drop a group?

但是我如何以编程方式删除 b 我添加了,但是其他所有分组却保持不变吗?

But how do I programmatically drop the grouping by b which I added, yet keep all other groupings the same?

推荐答案

这是一种使用tidyeval的方法,这样裸露的列名可以用作函数参数。我不确定将裸列名称转换为文本是否有意义(如我在下面所做的那样),或者是否有一种更优雅的方法可以直接使用裸列名称。

Here's an approach that uses tidyeval so that bare column names can be used as the function arguments. I'm not sure if it makes sense to convert the bare column names to text (as I've done below) or if there's a more elegant way to work directly with the bare column names.

drop_groups = function(data, ...) {

  groups = map_chr(groups(data), rlang::quo_text)
  drop = map_chr(quos(...), rlang::quo_text)

  if(any(!drop %in% groups)) {
    warning(paste("Input data frame is not grouped by the following groups:", 
                  paste(drop[!drop %in% groups], collapse=", ")))
  }

  data %>% group_by_at(setdiff(groups, drop))

}

d = mtcars %>% group_by(cyl, vs, am)

groups(d %>% drop_groups(vs, cyl))




[[1]]
am




groups(d %>% drop_groups(a, vs, b, c))




[[1]]
cyl

[[2]]
am

Warning message:
In drop_groups(., a, vs, b, c) :
  Input data frame is not grouped by the following groups: a, b, c


更新:以下方法有效直接使用保留的列名,而无需将其转换为字符串。我不确定在tidyeval范例中首选哪种方法,或者不确定是否还有另一种更理想的方法。

UPDATE: The approach below works directly with quosured column names, without converting them to strings. I'm not sure which approach is "preferred" in the tidyeval paradigm, or whether there is yet another, more desirable method.

drop_groups2 = function(data, ...) {

  groups = map(groups(data), quo)
  drop = quos(...)

  if(any(!drop %in% groups)) {
    warning(paste("Input data frame is not grouped by the following groups:", 
                  paste(drop[!drop %in% groups], collapse=", ")))
  }

  data %>% group_by(!!!setdiff(groups, drop))

}

这篇关于以编程方式在dplyr中删除`group_by`字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆