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

创建first.treat变量用于多期diff-in-diff时遇无从未处理组错误求助

问题描述

我有1997-2019年PSF覆盖数据,结构如下:

ano    id_mun    tratado
1998    313240      0
1998    313250      0
1998    313260      1
 .        .         .
 .        .         .
 .        .         .
2019    317220      1  

其中tratado=1表示市镇接受项目(处理组),0为未接受。我需要识别每个市镇首次被处理的年份,创建first.treat变量用于多期双重差分(DID)估计,使用了以下代码:

df1 = amostra_final%>% 
  group_by(id_mun) %>% 
  mutate(first.treat = min(
    if_else(tratado == 1, ano, NA_integer_),
    na.rm = TRUE
  )) %>% 
  ungroup()

运行后出现错误:

Error in pre_process_did(yname = yname, tname = tname, idname = idname,  : 
  There is no available never-treated group
问题原因

这个错误来自多期DID工具(比如did包)的前置检查:这类模型要求必须存在从未接受处理的对照组(即所有年份tratado都为0的市镇),但当前数据中所有市镇最终都被纳入了项目,没有始终未处理的样本;或者是first.treat变量的标记逻辑有误,导致工具无法识别已存在的从未处理组。

解决方案

1. 先确认是否真的没有从未处理的市镇

先运行代码排查数据状态:

# 统计每个市镇是否曾经被处理
mun_treat_status <- amostra_final %>%
  group_by(id_mun) %>%
  summarize(ever_treated = max(tratado))

# 查看从未处理的市镇数量
nrow(filter(mun_treat_status, ever_treated == 0))

如果结果为0,说明确实没有从未处理组,需要调整分析策略;如果结果大于0,说明是first.treat变量的标记有问题,直接看方案3。

2. 无从未处理组时的分析调整

方式一:采用相对时间模型

放弃依赖从未处理组,转而估计处理的动态效应,以每个市镇首次处理前的时期为基准:

# 创建相对时间变量
df1 <- amostra_final %>%
  group_by(id_mun) %>%
  mutate(
    first.treat = min(if_else(tratado == 1, ano, NA_integer_), na.rm = TRUE),
    # rel_time为负表示处理前,0为处理当年,正为处理后;从未处理的设为NA
    rel_time = ano - first.treat
  ) %>%
  ungroup()

# 用双向固定效应模型估计
library(lfe)
dynamic_model <- felm(y ~ rel_time | id_mun + ano, data = df1)
summary(dynamic_model)

方式二:使用合成控制法

如果处理组市镇数量较少,可为每个处理组构建“合成对照组”(由未处理时期的其他市镇加权组成),替代传统DID的从未处理组,适合用Synth或gsynth包实现。

3. 修正first.treat变量(存在从未处理组时)

如果实际有从未处理的市镇,但当前代码给它们的first.treat赋值为Inf(因为min(NA, na.rm=TRUE)返回无穷大),导致DID工具无法识别,需要手动标记从未处理组的first.treat为NA或超出样本范围的年份:

df1 <- amostra_final %>%
  group_by(id_mun) %>%
  mutate(
    first.treat = case_when(
      max(tratado) == 0 ~ NA_integer_,  # 从未处理的设为NA
      TRUE ~ min(if_else(tratado == 1, ano, NA_integer_), na.rm = TRUE)
    )
  ) %>%
  ungroup()

这样DID工具就能正确识别从未处理组作为对照组了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:11:14