基于发明人-年份面板的缺失firm_id值中点填充方法技术问询
问题描述
我有一份发明人-年份面板数据,存在以下特征:
- 仅当发明人产出专利时,才能观测到其工作单位(
firm_id),其余年份的firm_id为缺失值(NA) - 换工作节点定义为两次观测到工作单位的时间中点:
- 例1:发明人A在2001年供职于Firm A,2006年供职于Firm B,中点为2003.5 → 2001-2003年归Firm A,2004-2006年归Firm B;2009年观测到Firm C,中点为2007.5 → 2007年归Firm B,2008-2009年归Firm C
- 例2:发明人B在2005年供职于Firm D,2007年供职于Firm E,中点为2006 → 2006年归Firm E
- 数据规模:125万位发明人、630万条记录,包含未换工作(可直接用
fill填充)和换过工作的两类发明人
示例原始数据:
have <- data.frame( inventor_id=c('A','A','A','A','A','A','A','A','A','B','B','B'), firm_id=c('A',NA,NA,NA,NA,'B',NA,NA,'C','D',NA,'E'), fyear=c("2001", "2002","2003","2004","2005","2006","2007","2008","2009", "2005", "2006", "2007") )
期望输出数据:
want <- data.frame( inventor_id=c('A','A','A','A','A','A','A','A','A','B','B','B'), firm_id=c('A','A','A','B','B','B','B','C','C','D','E', 'E'), fyear=c("2001", "2002","2003","2004","2005","2006","2007","2008","2009", "2005", "2006", "2007") )
解决方案
使用tidyverse工具包进行向量化处理,兼顾效率和逻辑清晰,适合大规模数据:
library(tidyverse) # 1. 将年份转换为数值型,方便计算时间中点 have <- have %>% mutate(fyear = as.numeric(fyear)) # 2. 提取每个发明人的有效工作记录,计算对应的时间区间 firm_time_ranges <- have %>% filter(!is.na(firm_id)) %>% group_by(inventor_id) %>% mutate( # 下一次观测到工作单位的年份 next_obs_year = lead(fyear), # 计算当前工作单位与下一个工作单位的时间中点 mid_point = ifelse(is.na(next_obs_year), Inf, (fyear + next_obs_year) / 2), # 当前工作单位的起始边界(上一个工作区间的中点) start_bound = lag(mid_point, default = -Inf) ) %>% ungroup() %>% select(inventor_id, firm_id, start_bound, mid_point) # 3. 匹配每个年份对应的工作单位,完成填充 want <- have %>% left_join(firm_time_ranges, by = "inventor_id") %>% # 筛选当前年份落在对应工作区间的记录 filter(fyear > start_bound & fyear <= mid_point) %>% select(inventor_id, firm_id, fyear) %>% # 恢复原始排序 arrange(inventor_id, fyear) %>% # 可选:将年份转回字符型(若需要和原始格式一致) mutate(fyear = as.character(fyear))
方案说明
- 对于未换工作的发明人:其有效工作记录仅1条,
start_bound为-Inf,mid_point为Inf,所有年份都会匹配到该工作单位,等价于fill的效果 - 对于换过工作的发明人:通过时间中点划分区间,精准匹配每个年份对应的工作单位
- 向量化操作避免了循环,处理百万级数据效率较高
内容的提问来源于stack exchange,提问作者Torin McFarland
相关产品推荐
相关产品推荐

