在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
相关产品推荐
相关产品推荐

