根据累计和另一个分组创建分组

问题描述 投票:0回答:1

此问题与以下内容几乎相同:Create new group based on cumulative sum and group

但是,当我将接受的解决方案应用于我的数据时,它没有预期的结果。

简而言之,我有一个包含两个变量的数据:domainvalueDomain是具有多个观测值的组变量,value是我想由domain累加的某个连续值,并且是一个新的组变量newgroup。有三个主要规则:

  1. 我仅在每个domain中累积。如果我到达domain的末尾,则累计将重置。
  2. 如果累积总和至少为1.0,则将跨越的观察值分配给newgroup的不同值。
  3. 如果domain中的最后一个组的累积总和小于1.0,则将其与同一domain中的倒数第二个组合并。

示例数据

domain <- c(rep(1,5),rep(2,8))
value <- c(0,1,2,2.5,0.1,0.1,0.5,0,0.2,0.6,0,0,0.1)
df_raw <- data.frame(domain,value)


 domain value
      1   0.0
      1   1.0
      1   2.0
      1   2.5
      1   0.1
      2   0.1
      2   0.5
      2   0.0
      2   0.2
      2   0.6
      2   0.0
      2   0.0
      2   0.1

所需的输出

cumsum_val <- c(0,1,2,2.5,0.1,0.1,0.6,0.6,0.8,1.4,0,0,0.1)
newgroup <- c(1,1,2,3,3,4,4,4,4,4,4,4,4)
df_want <- data.frame(domain,value,cumsum_val,newgroup)

domain value cumsum_val group
      1   0.0        0.0     1
      1   1.0        1.0     1
      1   2.0        2.0     2
      1   2.5        2.5     3
      1   0.1        0.1     3
      2   0.1        0.1     4
      2   0.5        0.6     4
      2   0.0        0.6     4
      2   0.2        0.8     4
      2   0.6        1.4     4
      2   0.0        0.0     4
      2   0.0        0.0     4
      2   0.1        0.1     4

我使用了以下代码:

sum0 <- function(x, y) { if (x + y >= 1.0) 0 else x + y }
is_start <- function(x) head(c(TRUE, Reduce(sum0, init=0, x, acc = TRUE)[-1] == 0), -1)
cumsum(ave(df_raw$value, df_raw$domain, FUN = is_start))
## 1 2 3 4 5 6 6 6 6 6 7 8 9

但最后一行与上面的newgroup产生的值不同。问题的一部分是规则3,只要正确创建了前面的组,我就可以处理。但是,我希望前两个观察值具有相同的newgroup值。有人可以帮助我理解函数is_start以及该函数如何产生分组吗?

r dplyr cumsum
1个回答
1
投票
df_raw %>%
    group_by(domain) %>%
    mutate(grp = cumsum(value),
           grp = grp - lag(grp) > 1,
           grp = replace(grp, 1, 1)) %>%
    ungroup() %>%
    mutate(grp = cumsum(grp))
© www.soinside.com 2019 - 2024. All rights reserved.