You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言按Grp分组在Treat状态切换时生成连续计数序列列的实现

实现方案

核心逻辑:按Grp分组、按Year升序排序后,通过连续运行长度(RLE)识别每一段连续相同的Treat值,对非零的连续段从1开始累计计数,Treat为0时直接赋值为0。

方案1:dplyr 实现(简洁易读,日常开发首选)

library(dplyr)

df_result <- df %>%
  # 按分组、年份排序保证顺序符合要求
  arrange(Grp, Year) %>%
  group_by(Grp) %>%
  mutate(
    treat_rle = rle(Treat),
    # 对每个连续Treat段生成从1开始的累计序号
    seq = ifelse(Treat == "0", 0, sequence(treat_rle$lengths))
  ) %>%
  # 移除中间计算用的rle对象列
  select(-treat_rle) %>%
  ungroup()

方案2:基础R实现(无依赖,适配所有R环境)

# 先按分组、年份排序
df <- df[order(df$Grp, df$Year), ]
# 初始化seq列
df$seq <- 0

# 逐组处理
for (group in unique(df$Grp)) {
  row_idx <- df$Grp == group
  current_treat <- df$Treat[row_idx]
  # 计算连续值的运行长度
  rle_lengths <- rle(current_treat)$lengths
  # 生成连续段的累计计数
  current_seq <- sequence(rle_lengths)
  # 将Treat为0的位置赋值为0
  current_seq[current_treat == "0"] <- 0
  # 结果写回数据框
  df$seq[row_idx] <- current_seq
}

方案3:data.table实现(高性能,适配大数据量场景)

library(data.table)
# 转换为data.table格式
setDT(df)

df[order(Grp, Year), 
   seq := {
     current_treat <- Treat
     rle_lengths <- rle(current_treat)$lengths
     s <- sequence(rle_lengths)
     s[current_treat == "0"] <- 0
     .(s)
   }, 
   by = Grp]

注意:原始数据中Treat字段为字符型,判断零值时统一与字符"0"比较,直接与数值0比较会出现逻辑判断错误。


内容的提问来源于stack exchange,提问作者Chuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 18:45:04