在R语言中对连续递增1的随机序列进行分组
问题:按连续递增+1的序列分组
原始数据(存储在
df中):value 1 -2 2 -1 3 0 4 1 5 2 6 -3 7 -2 8 -1 9 0 10 1 11 -1 12 0 13 1 14 -10 15 -9 16 -8 17 -7
期望输出:每个分组内的序列值与前一个值的差值恒为+1,当差值不等于+1时开启新分组:
value group 1 -2 1 2 -1 1 3 0 1 4 1 1 5 2 1 6 -3 2 7 -2 2 8 -1 2 9 0 2 10 1 2 11 -1 3 12 0 3 13 1 3 14 -10 4 15 -9 4 16 -8 4 17 -7 4
用户尝试了以下dplyr代码,但分组结果不符合预期:
library(dplyr) df %>% group_by(grp = cumsum(coalesce(value == -lag(value, n = 1), TRUE)))
输出仅生成2组,无法正确识别序列间的跳转:
# A tibble: 17 × 2 # Groups: grp [2] value grp <dbl> <int> 1 -2 1 2 -1 1 3 0 1 4 1 1 5 2 1 6 -3 1 7 -2 1 8 -1 1 9 0 1 10 1 1 11 -1 2 12 0 2 13 1 2 14 -10 2 15 -9 2 16 -8 2 17 -7 2
df的dput代码:
df<-structure(list(value = c(-2, -1, 0, 1, 2, -3, -2, -1, 0, 1, -1, 0, 1, -10, -9, -8, -7)), class = "data.frame", row.names = c(NA, -17L))
解决方案
核心逻辑:判断当前值与前一个值的差值是否不等于1,若满足则标记为新分组起点,最后通过cumsum累计新分组标记得到分组ID。
dplyr实现
library(dplyr) df %>% mutate( # 标记新分组:第一个值默认是新分组起点,后续值与前一个差值≠1则标记 new_group = coalesce(value - lag(value) != 1, TRUE), # 累计新分组标记生成分组ID group = cumsum(new_group) ) %>% select(-new_group) # 移除辅助列,可选
运行结果:
value group 1 -2 1 2 -1 1 3 0 1 4 1 1 5 2 1 6 -3 2 7 -2 2 8 -1 2 9 0 2 10 1 2 11 -1 3 12 0 3 13 1 3 14 -10 4 15 -9 4 16 -8 4 17 -7 4
基础R实现
无需依赖第三方包,用diff计算差值:
# 生成新分组标记:第一个位置为TRUE,后续判断差值是否≠1 new_group <- c(TRUE, diff(df$value) != 1) # 累计标记得到分组ID df$group <- cumsum(new_group)
内容的提问来源于stack exchange,提问作者Quinten
相关产品推荐
相关产品推荐

