如何为含月年数据的TWFE回归添加领先项与滞后项?
为月年维度面板数据生成领先/滞后项(基于ISIC分组)
核心思路
要实现按ISIC分组、基于年月维度的领先/滞后项生成,核心是确保时间匹配的准确性:要么将年月转换为连续时间序列后用偏移函数,要么直接计算目标年月并通过匹配获取对应值。以下提供两种实用方法:
方法1:利用时间序列偏移函数(lead/lag)
适合时间序列连续的面板数据,按ISIC分组后,用dplyr的lead()(领先)和lag()(滞后)函数直接按排序后的时间偏移指定月份数。
代码示例
# 加载所需包 library(dplyr) library(lubridate) # 原数据 N = 10 ISIC <- c(111, 112, 113, 114, 115, 111, 112, 113, 114, 115) n_workers <- rnorm(N) year_month <- c(201801, 201801, 201802, 201801, 201802, 201901, 201902, 201901, 201902, 201903) year <- c(2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019) month <- c(1, 1, 2, 1, 2, 1, 2, 1, 2, 3) # 修正原数据中01转数值为1的问题 df <- data.frame(ISIC, n_workers, year_month, year, month) # 预处理:转换为日期格式并按ISIC+时间排序 df <- df %>% mutate(date = ym(year_month)) %>% arrange(ISIC, date) # 生成领先/滞后项 df <- df %>% group_by(ISIC) %>% mutate( n_workers_lag1 = lag(n_workers, n = 1), # 滞后1个月 n_workers_lag12 = lag(n_workers, n = 12), # 滞后1年(12个月) n_workers_lead1 = lead(n_workers, n = 1), # 领先1个月 n_workers_lead12 = lead(n_workers, n = 12) # 领先1年(12个月) ) %>% ungroup() # 查看结果 print(df)
方法2:通过年月匹配生成(适合时间序列不连续的情况)
如果面板数据存在时间缺失(比如部分ISIC某年月没有观测),直接用lead/lag会导致偏移错误,此时可以计算目标年月后通过左连接匹配,确保获取的是严格同月份的跨年度值(如201801的1年领先项为201901的值)。
代码示例
# 加载所需包 library(dplyr) # 原数据(同方法1) N = 10 ISIC <- c(111, 112, 113, 114, 115, 111, 112, 113, 114, 115) n_workers <- rnorm(N) year_month <- c(201801, 201801, 201802, 201801, 201802, 201901, 201902, 201901, 201902, 201903) year <- c(2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2019, 2019) month <- c(1, 1, 2, 1, 2, 1, 2, 1, 2, 3) df <- data.frame(ISIC, n_workers, year_month, year, month) # 统一格式:生成标准的YYYYMM数值型年月 df <- df %>% mutate(year_month_num = as.numeric(sprintf("%d%02d", year, month))) # 生成1年领先项:计算目标年月(当前年月+12个月)并匹配 df_lead12 <- df %>% mutate( target_year_month = case_when( month == 12 ~ (year + 1)*100 + 1, TRUE ~ year*100 + month + 12 ) ) %>% select(ISIC, target_year_month, n_workers_lead12 = n_workers) # 左连接回原数据 df <- df %>% left_join(df_lead12, by = c("ISIC", "year_month_num" = "target_year_month")) # 生成1年滞后项:计算目标年月(当前年月-12个月)并匹配 df_lag12 <- df %>% mutate( target_year_month = case_when( month == 1 ~ (year - 1)*100 + 12, TRUE ~ year*100 + month - 12 ) ) %>% select(ISIC, target_year_month, n_workers_lag12 = n_workers) # 左连接回原数据 df <- df %>% left_join(df_lag12, by = c("ISIC", "year_month_num" = "target_year_month")) # 查看结果 print(df)
注意事项
- 如果需要生成其他时间跨度的领先/滞后项,只需调整
lead/lag的n参数,或修改target_year_month的计算逻辑即可。 - 若数据中存在重复的
ISIC+year_month组合,需先去重或明确取数规则(如均值、总和),避免匹配时出现多对多的问题。
内容的提问来源于stack exchange,提问作者anrisakaki96
相关产品推荐
相关产品推荐

