假设我有这样的数据:
haves <- data.frame(
indicator = c(1,1,2,2,2,3,3,3,3,3,3,3,3)
)
指示器定义一组行,行按指示器排序。每个组的行计数如下:
sum_stats <- haves %>% group_by(indicator) %>% summarise(n = n()) %>% ungroup()
sum_stats
# A tibble: 3 x 2
indicator n
<dbl> <int>
1 1 2
2 2 3
3 3 8
假设我们的阈值为 5,只要总行数不超过阈值,我想合并连续的组。团体也永远不应该被拆散。因此,这个简化示例的需求是:
wants <- data.frame(
indicator = c(1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3)
, group = c(1,1,1,1,1,2,2,2,2,2,2,2,2)
)
wants
indicator group
1 1 1
2 1 1
3 2 1
4 2 1
5 2 1
6 3 2
7 3 2
8 3 2
9 3 2
10 3 2
11 3 2
12 3 2
13 3 2
这可能吗?任何意见将不胜感激。谢谢!
我认为这可能会对您有所帮助,因为我在扩展数据样本上尝试了它。以下是有关此解决方案的一些说明:
- 我决定使用
accumulate2
,因为我们想看看向量与其先前值(滞后值)的总和是否大于 5 - 因此,第一个向量将在没有最后一个元素的情况下
n
,第二个向量将在没有第一个元素的情况下再次n
- 在这里,我还创建了一个
tibble
,将我的新vargrp
放入其中,将grp
的第一个值设置为每个第一个分组值的1
值 - 应该注意的是,虽然
.init
.x
提供,但.y
(第一和第二向量)的长度可能相同,否则第二个.y
应该更短 - 由于
accumulate2
采用三参数函数来更好地区分我..1
使用的变量,..2
&..3
作为..1
是从.init
开始的累积值,..2
第一个向量序列中的下一个值n[-nrow(.)]
,并..3
第二个向量序列中的下一个值n[-1]
- 由于
..1
是grp
的累积/先前值,如果..2
和..3
的总和大于5
则保持原样,否则将被添加1
有关更多信息,您可以查看此页面。
library(dplyr)
library(tidyr)
library(purrr)
haves <- data.frame(
indicator = c(1,1,2,2,2,3,3,3,3,3,3,3,3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 8)
)
haves %>%
group_by(indicator) %>%
summarise(n = n()) %>%
ungroup() %>%
mutate(output = accumulate2(n[-nrow(.)], n[-1], .init = tibble(grp = 1),
~ tibble(grp = if(..2 + ..3 <= 5) {
..1$grp
} else {
..1$grp + 1
}))) %>%
unnest(output)
# A tibble: 8 x 3
indicator n grp
<dbl> <int> <dbl>
1 1 2 1
2 2 3 1
3 3 8 2
4 4 2 3
5 5 2 3
6 6 5 4
7 7 1 5
8 8 1 5
亲爱的 Ronak 有时会提到库MESS
,其中对于它的功能很有用,cumsumbinning
完全按照预期执行
library(dplyr, warn.conflicts = FALSE)
library(tidyr, warn.conflicts = FALSE)
library(MESS)
haves <- data.frame(
indicator = c(1,1,2,2,2,3,3,3,3,3,3,3,3)
)
haves %>%
count(indicator) %>%
mutate(xx = cumsumbinning(n, 5)) %>%
uncount(n)
#> indicator xx
#> 1 1 1
#> 2 1 1
#> 3 2 1
#> 4 2 1
#> 5 2 1
#> 6 3 2
#> 7 3 2
#> 8 3 2
#> 9 3 2
#> 10 3 2
#> 11 3 2
#> 12 3 2
#> 13 3 2
创建于 2021-07-10 由 reprex 软件包 (v2.0.0)