在R中按ID分组,基于val2值变化生成递增索引列val3
按ID分组生成自定义递增索引列val3
原始数据
创建数据的代码:
ID <- c('A','A','A','A','A','A','A','A','A','A','A','B','B','B','B','B') val1 <- c(0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3) val2 <- c(0,1,2,3,4,5,0,1,0,1,2,0,1,0,1,2) df <- data.frame(ID, val1, val2)
原始数据输出:
ID val1 val2 1 A 0 0 2 A 1 1 3 A 2 2 4 A 3 3 5 A 4 4 6 A 5 5 7 A 6 0 8 A 7 1 9 A 8 0 10 A 9 1 11 A 10 2 12 B 11 0 13 B 0 1 14 B 1 0 15 B 2 1 16 B 3 2
需求说明
需要新增索引列val3,规则如下:
- 按
ID分组处理 - 组内首次遇到
val2=0时,val3为1 - 后续每次遇到
val2=0时,val3递增1 - 其余行保持当前的
val3值
期望输出:
ID val1 val2 val3 1 A 0 0 1 2 A 1 1 1 3 A 2 2 1 4 A 3 3 1 5 A 4 4 1 6 A 5 5 1 7 A 6 0 2 8 A 7 1 2 9 A 8 0 3 10 A 9 1 3 11 A 10 2 3 12 B 11 0 1 13 B 0 1 1 14 B 1 0 2 15 B 2 1 2 16 B 3 2 2
之前尝试的错误方法
第一种方法(分组逻辑错误):
df <- df %>% group_by(ID, val2) %>% mutate(val3 = row_number())
第二种方法(未分组且逻辑不符):
df$val3 <- cumsum(c(1,diff(df$val2)==0))
正确解法
使用dplyr按ID分组后,通过累加val2==0的逻辑标记来生成val3:
library(dplyr) df <- df %>% group_by(ID) %>% mutate(val3 = cumsum(val2 == 0)) %>% ungroup()
逻辑说明
group_by(ID):确保每个ID组内独立计算索引val2 == 0:生成逻辑向量,val2为0的行标记为TRUE(等价于1),其余行标记为FALSE(等价于0)cumsum(...):对逻辑向量做累加,每次遇到val2=0时累加1,其余行保持当前累加值,完全匹配需求的val3规则
运行上述代码后,即可得到期望的输出结果。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

