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

在R语言中创建状态持续时长(Duration)变量的问题求助

问题描述

现有一份多个体多年观测数据集,每个个体每年状态为A或B之一。已生成虚拟变量Status_change:当年状态与上年不同时取值1,否则0(第一年为NA)。需要创建Duration变量,规则为:

  • 个体第一年取值0
  • 状态不变时每年加1
  • 状态切换时重置为0

尝试以下R代码后报错:

data%>%
  group_by(Individual)%>%
  arrange(Year, .by_group = TRUE)%>%
  mutate(Duration = ifelse(Year == 1, 0, ifelse(Status_Change == 1, 0, lag(Duration) + 1)))

报错信息:

Error: Problem with `mutate()` column `Duration`.
i `Duration = ifelse(Year == 1, 0, ifelse(Status_Change == 1, 0, lag(Duration) + 1))`.
x could not find function "Duration"
i The error occurred in group 1: Individual = "1"
错误原因

dplyr::mutate中无法直接引用正在创建的变量的lag()值——因为Duration还未完全生成,代码执行时无法识别该变量,导致报错。

解决方法

提供两种可行方案,任选其一即可:

方案1:用purrr::accumulate迭代计算

利用迭代函数逐行计算,依赖前一行的Duration值:

library(dplyr)
library(purrr)

data_processed <- data %>%
  group_by(Individual) %>%
  arrange(Year, .by_group = TRUE) %>%
  mutate(
    Duration = accumulate(2:n(), .init = 0, 
                          ~ ifelse(Status_Change[.y] == 1, 0, .x + 1))
  )
  • .init = 0指定第一年的Duration值
  • 从第2行开始迭代:若Status_Change为1则重置为0,否则前一行值加1

方案2:用分组累积ID计算

通过生成连续相同状态的分组ID,再计算组内行号实现:

library(dplyr)

data_processed <- data %>%
  group_by(Individual) %>%
  arrange(Year, .by_group = TRUE) %>%
  # 将第一年的NA替换为0,生成连续状态的分组ID
  mutate(status_group = cumsum(coalesce(Status_Change, 0))) %>%
  # 在每个个体+状态分组内计算Duration
  group_by(Individual, status_group) %>%
  mutate(Duration = row_number() - 1) %>%
  ungroup() %>%
  # 可选:删除中间变量
  select(-status_group)
  • coalesce(Status_Change, 0)处理第一年的NA,确保分组ID从0开始
  • 每次状态切换时status_group递增,新分组内row_number()-1重新从0计数

内容的提问来源于stack exchange,提问作者Student In Need

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:35:22