将数据拆分为块,同时尊重组和阈值

  • 本文关键字:重组 阈值 数据 拆分 r
  • 更新时间 :
  • 英文 :


假设我有这样的数据:

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]
  • 由于..1grp的累积/先前值,如果..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)

最新更新