如何使用 R 和 dplyr 中连续的元素执行 group_by

Posted

技术标签:

【中文标题】如何使用 R 和 dplyr 中连续的元素执行 group_by【英文标题】:How to perform a group_by with elements that are contiguous in R and dplyr 【发布时间】:2017-11-23 05:43:47 【问题描述】:

假设我们有这个小标题:

 group item
 x     1
 x     2
 x     2
 y     3
 z     2
 x     2
 x     2
 z     1

我想按组执行 group_by。但是,我宁愿只按相邻的元素进行分组。例如,在我的情况下,我将有三个“x”组,将“项目”元素相加。结果会是这样的:

group item
x 5
y 3
z 2
x 4
z 1

我知道如何使用“for”循环来解决这个问题。但是,这并不快,而且听起来也不简单。我宁愿使用一些逻辑简单的 dplyr 或 tidyverse 函数。

这个问题没有重复。我知道在 SO 中已经有一个关于 rle 的问题,但我的问题比这更笼统。我要求通用解决方案。

【问题讨论】:

【参考方案1】:

如果您只想使用基本 R + tidyverse,此代码完全复制了您想要的结果

mydf <- tibble(group = c("x", "x", "x", "y", "z", "x", "x", "z"), 
                   item = c(1, 2, 2, 3, 2, 2, 2, 1))

mydf

# A tibble: 8 × 2
  group  item
  <chr> <dbl>
1     x     1
2     x     2
3     x     2
4     y     3
5     z     2
6     x     2
7     x     2
8     z     1

runs <- rle(mydf$group)

mydf %>% 
  mutate(run_id = rep(seq_along(runs$lengths), runs$lengths)) %>% 
  group_by(group, run_id) %>% 
  summarise(item = sum(item)) %>% 
  arrange(run_id) %>% 
  select(-run_id) 

Source: local data frame [5 x 2]
Groups: group [3]

  group  item
  <chr> <dbl>
1     x     5
2     y     3
3     z     2
4     x     4
5     z     1

【讨论】:

【参考方案2】:

您可以使用rle 构造组标识符,但更简单的方法是使用data.table::rleid,它会为您完成:

library(dplyr)

df %>% 
    group_by(group, 
             group_run = data.table::rleid(group)) %>% 
    summarise_all(sum)
#> # A tibble: 5 x 3
#> # Groups:   group [?]
#>    group group_run  item
#>   <fctr>     <int> <int>
#> 1      x         1     5
#> 2      x         4     4
#> 3      y         2     3
#> 4      z         3     2
#> 5      z         5     1

【讨论】:

以上是关于如何使用 R 和 dplyr 中连续的元素执行 group_by的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中使用 broom 和 dplyr 进行“多步”回归

在 R 中使用 dplyr 在 group_by 之后应用自定义函数

基于观察分布/频率的连续数据分箱来决定分箱范围 r dplyr

如何在 R 中的 bar-line Plotly 对象中绘制连续线?

如何通过使用 dplyr 或其他包在 R 中具有最小值和最大值的查询来实现组?

如何使用 R 和 dplyr 从 Redshift 检索超过 100000 行