如何用dplyr实现:col1变化重置计数,col2变化递增计数
问题:基于col1重置、col2变化递增的计数实现
需求:通过mutate()实现计数逻辑——当col2行值变化时,count列递增;当col1行值变化时,count列重置为1。
期望输出
col1 col2 count 0 1 1 0 1 1 0 2 2 0 3 3 1 4 1 1 5 2 1 5 2
当前错误输出
仅col1重置逻辑生效,col2重复行的计数仍递增:
col1 col2 count 0 1 1 0 1 2 0 2 3 0 3 4 1 4 1 1 5 2 1 5 3
已尝试的代码
代码1:
df1 <- df %>% group_by(col1, col2)%>% mutate(counter=row_number())%>% ungroup
代码2:
df1 <- df %>% group_by(col1)%>% mutate(counter=row_number())%>% group_by(col2)%>% mutate(counter= 'failed_code')%>% ungroup
尝试if_else/case_when时参数设置未生效,寻求正确实现方式。
解决方案
核心逻辑:按col1分组,在组内对首次出现的col2值进行累加计数,重复值保持同一计数。
纯dplyr实现(无需额外包)
library(dplyr) df1 <- df %>% group_by(col1) %>% mutate(count = cumsum(!duplicated(col2))) %>% ungroup()
代码解释
group_by(col1):限定计数在每个col1分组内独立计算,col1切换时自动重置计数。duplicated(col2):标记当前行的col2是否在同组的之前行中出现过。!duplicated(col2):将首次出现的col2转为TRUE(对应数值1),重复值转为FALSE(对应数值0)。cumsum():对上述0/1值累加,实现“col2变化时计数+1,重复时保持计数”的效果。
验证示例
若原始数据为:
df <- tibble(col1 = c(0,0,0,0,1,1,1), col2 = c(1,1,2,3,4,5,5))
运行代码后得到的count列完全匹配期望输出。
原代码问题分析
- 代码1:
group_by(col1, col2)后用row_number(),会在每个(col1, col2)子组内生成行号,导致同col2的行计数递增,不符合需求。 - 代码2:先按
col1生成全局行号,再按col2分组覆盖,逻辑混乱,完全偏离需求。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

