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

如何用R筛选面板数据中含cutoff date前后观测值的企业?

筛选跨2017年临界点的企业面板数据解决方案

需求与数据说明

我们需要从企业面板数据中筛选出同时满足两个条件的企业:

  • 至少有一条观测记录在2017年之前
  • 至少有一条观测记录在2017年及之后

示例数据

df <- data.frame(year = rep(c(2010,2012,2017,
                              2010,2012,2017,
                              2008,2009,2018,
                              2017,2008,2009,
                              2017,2008,2009,
                              2005,2004,2002,
                              2003,2004,2008, 2020)),
                 company = rep(c("A", "A", "A", "B", "B", "C", "C", "D", "D", "E", "E",
                                 "F", "G", "G", "G", "H", "H", "I", "J", "K", "K", "K")))

数据预览:

year company
2010       A
2012       A
2017       A
2010       B
2012       B
2017       C
2008       C
2009       D
2018       D
2017       E
2008       E
2009       F
2017       G
2008       G
2009       G
2005       H
2004       H
2002       I
2003       J
2004       K
2008       K
2020       K

预期结果

最终应筛选出的企业:A、C、D、E、G、K

原代码问题分析

你尝试的代码无法得到正确结果,问题出在没有按企业分组判断:
原代码逐行标记pre和post,但单一行的年份不可能同时小于2017和大于2017,自然筛选不到任何数据。即使加了group_by,如果没有用分组级别的判断逻辑,依然无法解决问题。

原代码:

df <- df %>% 
  mutate(pre = case_when(year < 2017 ~ 1),
         post = case_when(year > 2017 ~ 1)) %>%
  mutate(both = pre + post) %>%
  filter(both == 2)

优雅解决方案

方法1:dplyr分组筛选(推荐)

通过group_by(company)按企业分组,用any()判断该企业是否存在符合条件的观测,最后保留满足双条件的企业所有记录:

library(dplyr)

# 获取筛选后的完整数据集
result_df <- df %>%
  group_by(company) %>%
  filter(any(year < 2017) & any(year >= 2017)) %>%
  ungroup()

# 如果只需要符合条件的企业名称列表
target_companies <- df %>%
  group_by(company) %>%
  filter(any(year < 2017) & any(year >= 2017)) %>%
  distinct(company) %>%
  pull(company)

方法2:base R原生实现

无需加载第三方包,通过聚合年份范围来判断:

# 计算每个企业的最小和最大年份
company_year_stats <- aggregate(year ~ company, df, function(x) c(min = min(x), max = max(x)))

# 筛选符合条件的企业
target_companies <- company_year_stats$company[
  company_year_stats$year[, "min"] < 2017 & 
  company_year_stats$year[, "max"] >= 2017
]

# 获取对应数据
result_df <- df[df$company %in% target_companies, ]

方法3:data.table高效处理(适合大数据)

如果数据集规模较大,data.table的分组操作效率显著更高:

library(data.table)
setDT(df)

result_df <- df[, if(any(year < 2017) & any(year >= 2017)) .SD, by = company]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:20:25