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

在R语言中按分组随时间创建条件递增的分类变量

问题

我有一个按用户分组、按时间排序的数据框,其中包含一个表示用户状态的二进制字段Status(0代表退出状态,1代表处于状态)。我需要为每个用户生成一个Status_Count字段:

  • 当用户进入或重新进入状态(即从0变为1)时,计数器递增
  • 同一状态周期内的所有时间点,计数器保持相同值
  • 退出状态时(Status=0),计数器显示0

期望输出

Date        User_ID   Status  Status_Count
01/01/2022     1        0        0
01/02/2022     1        0        0
01/03/2022     1        1        1
01/04/2022     1        1        1
01/05/2022     1        1        1
01/06/2022     1        0        0
01/07/2022     1        0        0
01/08/2022     1        1        2
01/09/2022     1        1        2
01/10/2022     1        0        0
01/11/2022     1        0        0
01/12/2022     1        0        0
01/01/2022     2        0        0
01/02/2022     2        1        1
01/03/2022     2        1        1
01/04/2022     2        1        1
01/05/2022     2        0        0
01/06/2022     2        0        0
01/07/2022     2        1        2
01/08/2022     2        1        2
01/09/2022     2        0        0
01/10/2022     2        0        0
01/11/2022     2        1        3
01/12/2022     2        0        0 

示例数据

Date <- rep(seq(as.Date('2022-01-01'), as.Date('2022-12-01'), by = "month"), 2)
User_ID <- c(rep.int(1, 12), rep.int(2, 12))
Status<- c(0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0)
Status_Counter <- c(0, 0, 1, 1, 1, 0, 0, 2, 2, 0, 0, 0, 0, 1, 1, 1, 0, 0, 2, 2, 0, 0, 3, 0)
Example_Data <- data.frame(Date, User_ID, Status, Status_Counter)

尝试的代码(存在问题)

library(dplyr)

Example_Data <- Example_Data %>%
  group_by(User_ID) %>%
  dplyr::mutate(Counter = case_when(
      Event == 1 & (Status != lag(Status, 1) | is.na(lag(Status, 1))) ~ cumsum(Status),
      Event == 1 ~ cumsum(Status),
      TRUE ~ 0))

解决方案

核心思路是先识别每个用户的状态进入事件(从0切换到1),再基于这些事件生成分组计数器,最后对退出状态的行做置0处理。用dplyr实现的完整代码如下:

library(dplyr)

Example_Data <- Example_Data %>%
  group_by(User_ID) %>%
  # 标记状态进入事件:从0→1的时刻标记为1,其余为0
  mutate(enter_event = ifelse(Status == 1 & (is.na(lag(Status)) | lag(Status) == 0), 1, 0),
         # 累加事件得到状态周期的序号
         cycle_num = cumsum(enter_event),
         # 状态为0时计数器置0,否则保留周期序号
         Status_Count = ifelse(Status == 0, 0, cycle_num)) %>%
  # 移除中间辅助列(可选操作)
  select(-enter_event, -cycle_num) %>%
  ungroup()

代码说明

  • enter_event:精准捕捉每个用户的状态进入节点,只有当当前状态为1且上一个状态为0(或为用户第一条记录)时,才标记为1
  • cycle_num:对进入事件做累加,每遇到一个进入事件序号就加1,同一状态周期内的所有行共享同一个序号
  • Status_Count:将状态为0的行计数器置为0,状态为1的行保留对应的周期序号,完全匹配需求的输出格式

运行后即可得到你期望的Status_Count字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:57:12