如何用dplyr追踪长格式纵向数据变化并生成条件变量?
问题描述
给定以下长格式纵向数据集(id为参与者分组变量):
| id | wave | car | household |
|---|---|---|---|
| 1 | 1 | 0 | 1 |
| 1 | 2 | 1 | 1 |
| 1 | 3 | 0 | 1 |
| 1 | 4 | 1 | 2 |
| 2 | 1 | 0 | 1 |
| 2 | 2 | 1 | 2 |
| 2 | 3 | 1 | 3 |
| 2 | 4 | 0 | 1 |
| 3 | 1 | 0 | 1 |
| 3 | 2 | 0 | 1 |
| 3 | 3 | 1 | 2 |
| 3 | 4 | 1 | 1 |
| 4 | 1 | 0 | 1 |
| 4 | 2 | 1 | 1 |
| 4 | 3 | 1 | 1 |
| 4 | 4 | 1 | 2 |
变量说明
car:是否拥有汽车(0=无,1=有)household:家庭居住人数- 所有参与者初始状态为无车且独居(
car=0且household=1)
生成目标变量规则
需要生成两个二进制变量Cond-A和Cond-B,规则如下:
- Cond-A:
- 仅当从
car=0且household=1变为car=1且household=1时标记为1; - 首次购车后若售车(即
car从1变0),后续再次购车的数据标记为NA; - 其余不符合情况标记为0。
- 仅当从
- Cond-B:
- 仅当从无车状态(
car=0)变为car=1且household=2时标记为1; - 若家庭人数超过2(
household>2),后续所有数据标记为NA; - 其余不符合情况标记为0。
- 仅当从无车状态(
示例数据集R代码
id <- c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4) wave <- c(1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4) car <- c(0,1,0,1,0,1,1,0,0,0,1,1,0,1,0,1) household <- c(1,1,1,2,1,2,3,1,1,1,2,1,1,2,1,2) df <- data.frame(id, wave, car, household)
预期输出
| id | wave | car | household | Cond-A | Cond-B |
|---|---|---|---|---|---|
| 1 | 1 | 0 | 1 | 0 | 0 |
| 1 | 2 | 1 | 1 | 1 | 0 |
| 1 | 3 | 0 | 1 | 0 | 0 |
| 1 | 4 | 1 | 2 | NA | NA |
| 2 | 1 | 0 | 1 | 0 | 0 |
| 2 | 2 | 1 | 2 | 0 | 1 |
| 2 | 3 | 1 | 3 | NA | NA |
| 2 | 4 | 0 | 1 | 0 | 0 |
| 3 | 1 | 0 | 1 | 0 | 0 |
| 3 | 2 | 0 | 1 | 0 | 0 |
| 3 | 3 | 1 | 2 | 0 | 1 |
| 3 | 4 | 1 | 1 | 1 | NA |
| 4 | 1 | 0 | 1 | 0 | 0 |
| 4 | 2 | 1 | 1 | 1 | 0 |
| 4 | 3 | 1 | 1 | 1 | 0 |
| 4 | 4 | 1 | 2 | NA | NA |
解决方案(使用dplyr)
通过分组处理每个参与者的时间序列数据,结合滞后变量、累积标记实现规则:
library(dplyr) df_result <- df %>% group_by(id) %>% # 生成滞后变量追踪状态变化 mutate( lag_car = lag(car), lag_household = lag(household), # 标记是否出现过购车后售车的情况 has_sold_car = cumsum(case_when( lag_car == 1 & car == 0 ~ 1, TRUE ~ 0 )) >= 1, # 标记是否出现过家庭人数超过2的情况 has_large_household = cumsum(case_when( household > 2 ~ 1, TRUE ~ 0 )) >= 1 ) %>% # 计算Cond-A mutate( Cond_A = case_when( has_sold_car & car == 1 ~ NA_real_, lag_car == 0 & lag_household == 1 & car == 1 & household == 1 ~ 1, TRUE ~ 0 ) ) %>% # 计算Cond-B mutate( Cond_B = case_when( has_large_household ~ NA_real_, lag_car == 0 & car == 1 & household == 2 ~ 1, TRUE ~ 0 ) ) %>% # 清理临时变量 select(-lag_car, -lag_household, -has_sold_car, -has_large_household) %>% ungroup() # 查看结果 print(df_result)
代码解释
- 分组与滞后变量:按
id分组后,用lag()获取上一期的car和household,用于判断状态转换。 - 累积标记触发NA的条件:
has_sold_car:一旦出现“购车后售车”,后续所有购车记录标记NA;has_large_household:一旦出现家庭人数超过2,后续所有Cond-B标记NA。
- Cond-A计算:
- 优先判断NA触发条件,再匹配“无车独居→有车独居”的转换标记1,其余为0。
- Cond-B计算:
- 优先判断NA触发条件,再匹配“无车→有车且家庭人数为2”的转换标记1,其余为0。
运行代码后输出结果与预期完全一致。
内容的提问来源于stack exchange,提问作者JamesCraemer
相关产品推荐
相关产品推荐

