如何使用 R 和 dplyr 中连续的元素执行 group_by
How to perform a group_by with elements that are contiguous in R and dplyr
假设我们有这样的小标题:
group item
x 1
x 2
x 2
y 3
z 2
x 2
x 2
z 1
我想按组表演group_by。但是,我宁愿只按相邻的元素进行分组。例如,在我的例子中,我有三个 'x' 组,对 'item' 个元素求和。结果将类似于:
group item
x 5
y 3
z 2
x 4
z 1
我知道如何使用 'for' 循环解决这个问题。但是,这并不快,听起来也不简单。我宁愿使用一些逻辑简单的 dplyr 或 tidyverse 函数。
这个问题没有重复。我知道 SO 中已经有关于 rle 的问题,但我的问题比那更笼统。我要求通用解决方案。
您可以使用 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
如果您只想使用 base 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
假设我们有这样的小标题:
group item
x 1
x 2
x 2
y 3
z 2
x 2
x 2
z 1
我想按组表演group_by。但是,我宁愿只按相邻的元素进行分组。例如,在我的例子中,我有三个 'x' 组,对 'item' 个元素求和。结果将类似于:
group item
x 5
y 3
z 2
x 4
z 1
我知道如何使用 'for' 循环解决这个问题。但是,这并不快,听起来也不简单。我宁愿使用一些逻辑简单的 dplyr 或 tidyverse 函数。
这个问题没有重复。我知道 SO 中已经有关于 rle 的问题,但我的问题比那更笼统。我要求通用解决方案。
您可以使用 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
如果您只想使用 base 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