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

基于另一数据集观测值筛选数据集:保留t-1/t+1观测并生成POST变量

解决方案(R语言)

问题背景

我们有两个数据集:

  • 全量数据集:包含多家公司连续年度的记录(示例为公司6、7的2005-2022年数据)
  • 事件数据集:记录特定公司的关键事件年份

需要从全量数据中提取每个事件年份的**前一年(标记POST=0)和后一年(标记POST=1)**的观测值,最终输出符合要求的结果。


步骤1:构造示例数据

先还原题目中的两个数据集:

# 全量数据集
df_full <- data.frame(
  year = rep(2005:2022, 2),
  CompanyID = rep(6:7, each = 18)
)

# 事件数据集
df_events <- data.frame(
  year = c(2012, 2007, 2015, 2009),
  CompanyID = c(6,6,7,7)
)

步骤2:dplyr高效处理(推荐,适合大量数据)

使用dplyr包的向量化操作,批量生成目标记录并匹配:

library(dplyr)
library(tidyr) # 用于unnest函数

df_result <- df_events %>%
  # 为每个事件年份生成前后两年及对应POST标记
  mutate(
    year = list(c(year - 1, year + 1)),
    POST = list(c(0, 1))
  ) %>%
  # 展开列表为多行记录
  unnest(c(year, POST)) %>%
  # 与全量数据匹配,自动过滤不存在的年份(比如事件在2005年时t-1=2004会被排除)
  inner_join(df_full, by = c("CompanyID", "year")) %>%
  # 按公司ID和年份排序,与预期输出一致
  arrange(CompanyID, year)

# 输出结果
print(df_result)

运行后得到的结果与题目预期完全一致:

year CompanyID POST
1 2006         6    0
2 2008         6    1
3 2011         6    0
4 2013         6    1
5 2008         7    0
6 2010         7    1
7 2014         7    0
8 2016         7    1

步骤3:Base R原生处理(无需加载包)

如果不想依赖第三方包,可以用Base R的批量处理方式:

# 生成所有需要提取的(year, CompanyID, POST)组合
target_records <- do.call(rbind, lapply(1:nrow(df_events), function(i) {
  data.frame(
    year = c(df_events$year[i]-1, df_events$year[i]+1),
    CompanyID = df_events$CompanyID[i],
    POST = c(0, 1)
  )
}))

# 与全量数据匹配并排序
df_result_base <- merge(df_full, target_records, by = c("CompanyID", "year"))
df_result_base <- df_result_base[order(df_result_base$CompanyID, df_result_base$year), ]
rownames(df_result_base) <- NULL # 重置行名

# 输出结果
print(df_result_base)

适用场景

两种方法都支持大量不同CompanyID的场景,处理逻辑是批量生成目标记录再匹配,不会因为公司数量增加导致性能瓶颈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:23:21