此问题与以下内容几乎相同:Create new group based on cumulative sum and group
但是,当我将接受的解决方案应用于我的数据时,它没有预期的结果。
简而言之,我有一个包含两个变量的数据:domain
和value
。 Domain
是具有多个观测值的组变量,value
是我想由domain
累加的某个连续值,并且是一个新的组变量newgroup
。有三个主要规则:
domain
中累积。如果我到达domain
的末尾,则累计将重置。newgroup
的不同值。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
以及该函数如何产生分组吗?
df_raw %>%
group_by(domain) %>%
mutate(grp = cumsum(value),
grp = grp - lag(grp) > 1,
grp = replace(grp, 1, 1)) %>%
ungroup() %>%
mutate(grp = cumsum(grp))