如何在R语言中按分组从满足qresult==1时开始计数
按分组生成条件计数列的R语言实现
首先给出原始数据框:
df <- data.frame ( id = c(1,1,1,2,2,2,3,3,3,3,4,4,4,4,4,4), qresult = c(0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0), count = c(0,0,0,0,1,2,0,0,1,2,1,2,3,4,5,6) )
需求说明:在每个id分组内,当首次出现qresult==1时开始计数(起始值为1,后续每行递增1),未出现该条件的行值为0;每个新的id分组需重置计数逻辑。
方法一:使用tidyverse(dplyr)实现
library(dplyr) df <- df %>% group_by(id) %>% mutate( # 标记分组内是否已出现过qresult==1 trigger = cumsum(qresult == 1) > 0, # 生成目标计数列 count_new = ifelse(trigger, cumsum(trigger), 0) ) %>% ungroup()
逻辑说明:
- 按
id分组后,cumsum(qresult == 1)会累计分组内1的出现次数,一旦出现过1,后续行的结果都会大于0,以此标记计数的起始点。 cumsum(trigger)会对标记为TRUE的行累加计数,实现从1开始的连续递增,未触发的行保持0。
方法二:使用Base R实现
df$count_new <- ave(df$qresult, df$id, FUN = function(x) { # 找到分组内第一个qresult==1的位置 first_occur <- which(x == 1)[1] if (is.na(first_occur)) { # 若分组内无1,返回全0 rep(0, length(x)) } else { # 前半部分为0,后半部分从1开始计数 c(rep(0, first_occur - 1), seq_len(length(x) - first_occur + 1)) } })
逻辑说明:
- 用
ave函数按id分组处理qresult列,每个分组内先定位第一个1的位置。 - 若分组内没有1,直接返回全0;若有1,则前半部分行设为0,后半部分从1开始生成连续序列。
执行后查看结果:
print(df)
输出结果会和示例中的count列完全匹配,满足需求。
内容的提问来源于stack exchange,提问作者23stacks1254
相关产品推荐
相关产品推荐

