全个体分时点处理的R语言Diff-in-Diff实现问询
多时点双重差分(Staggered DID)在feols中的实现方案
针对你这种所有个体最终都会接受处理但时点不同的人-日数据集,核心是用**相对处理时间(Days_To_Treatment)**构建动态或趋势型双重差分模型,完全不需要剔除处理前(Days_To_Treatment<0)的观测,以下是具体实现方法:
前提准备:计算相对处理时间
首先确保数据集里有个体ID、数值型日期(比如从1开始的天数)、个体处理日期(treat_date),然后计算相对时间:
library(dplyr) library(fixest) # 计算Days_To_Treatment:日期与个体处理日期的差值 data <- data %>% mutate(Days_To_Treatment = date - treat_date)
这里Days_To_Treatment为负代表处理前,0为处理当天,正数为处理后。
方法一:动态效应模型(推荐,可观察处理前后每日效应)
这种方法能看到处理前、处理当天、处理后每一天的效应变化,适合分析处理的动态影响:
- 对相对时间分组(合并过远的处理前/后组,避免维度爆炸)
- 用
fixest的i()函数生成相对时间哑变量,指定基准组(比如处理前1天) - 加入个体固定效应和日期固定效应
# 分组相对时间:合并提前7天以上和滞后7天以上的观测 data <- data %>% mutate(rel_time = case_when( Days_To_Treatment <= -7 ~ "-7+", Days_To_Treatment >= 7 ~ "7+", TRUE ~ as.character(Days_To_Treatment) )) # 转换为因子并设置基准组(处理前1天,即"-1") data$rel_time <- factor(data$rel_time, levels = c("-7+", "-6", "-5", "-4", "-3", "-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7+")) # 运行模型 dynamic_model <- feols(y ~ i(rel_time, ref = "-1") | id + date, data = data) # 查看结果(包括各时间点的处理效应) summary(dynamic_model)
这个模型会保留所有观测,自动将未到处理时点的个体作为同期处理个体的对照组,完全不会剔除处理前的样本。
方法二:趋势型模型(看处理前后的整体趋势变化)
如果不需要每日动态效应,只想看处理前后的趋势差异,可以构造Post变量(处理后为1,处理前为0),然后与Days_To_Treatment交互:
# 构造Post变量:处理当天及之后为1,处理前为0 data <- data %>% mutate(Post = as.integer(Days_To_Treatment >= 0)) # 运行趋势模型 trend_model <- feols(y ~ Days_To_Treatment + Post:Days_To_Treatment | id + date, data = data) summary(trend_model)
Days_To_Treatment的系数代表处理前的时间趋势Post:Days_To_Treatment的系数代表处理后的趋势变化量
同样,所有观测都会被纳入分析,不会丢失处理前的样本。
为什么之前的方法会剔除观测?
你提到的"与Treatment交互导致Days_To_Treatment<0的观测被剔除",大概率是因为错误地将Treatment定义为仅包含处理后样本,或在模型中加入了subset=Treatment==1之类的筛选条件。上述两种方法都保留了全量样本,通过固定效应和相对时间变量实现了多时点DID的逻辑。
内容的提问来源于stack exchange,提问作者DellasZi
相关产品推荐
相关产品推荐

