如何在R中为存在周期不等长的分组补全面板数据缺失行?
问题
我们需要处理一份包含行政区行政长官及其就职年份的DataFrame,构建2000-2004年的面板数据,要求仅保留各行政区实际存在年份的有效数据,补全该区间内的缺失年份行,同时避免为行政区创建前的年份填充无效数据。
初始数据
df <- data.frame(year= c(2000, 2001, 2003, 2000, 2002, 2004, 2003), executive.name= c("Johnson", "Smith", "Alleghany", "Roberts", "Clarke", "Tollson", "Roland"), party= c("PartyRed", "PartyYellow", "PartyGreen", "PartyYellow", "PartyOrange", "PartyRed", "PartyPurple"), district= c(1001, 1001, 1001, 1002, 1002, 1002, 1003))
初始数据预览:
year executive.name party district 1 2000 Johnson PartyRed 1001 2 2001 Smith PartyYellow 1001 3 2003 Alleghany PartyGreen 1001 4 2000 Roberts PartyYellow 1002 5 2002 Clarke PartyOrange 1002 6 2004 Tollson PartyRed 1002 7 2003 Roland PartyPurple 1003
期望结果
最终需要得到仅包含各行政区存在年份的面板数据,例如1003号行政区仅保留2003-2004年的数据:
df.neat <- data.frame(year= c(2000, 2001, 2002, 2003, 2004, 2000, 2001, 2002, 2003, 2004, 2003, 2004), executive.name= c("Johnson", "Smith", "Smith", "Alleghany", "Alleghany", "Roberts", "Roberts", "Clarke", "Clarke", "Tollson", "Roland", "Roland"), party= c("PartyRed", "PartyYellow", "PartyYellow", "PartyGreen", "PartyGreen", "PartyYellow", "PartyYellow", "PartyOrange", "PartyOrange", "PartyRed", "PartyPurple", "PartyPurple"), district= c(1001, 1001, 1001, 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1003, 1003))
预览:
year executive.name party district 1 2000 Johnson PartyRed 1001 2 2001 Smith PartyYellow 1001 3 2002 Smith PartyYellow 1001 4 2003 Alleghany PartyGreen 1001 5 2004 Alleghany PartyGreen 1001 6 2000 Roberts PartyYellow 1002 7 2001 Roberts PartyYellow 1002 8 2002 Clarke PartyOrange 1002 9 2003 Clarke PartyOrange 1002 10 2004 Tollson PartyRed 1002 11 2003 Roland PartyPurple 1003 12 2004 Roland PartyPurple 1003
现有代码的问题
直接使用complete()+fill()会错误地为行政区创建前的年份填充无效数据(比如1003号行政区的2000-2002年被填充了Tollson的信息):
df |> tidyr::complete(district, year) |> tidyr::fill(executive.name, party)
错误结果中1003号的无效行:
11 1003 2000 Tollson PartyRed 12 1003 2001 Tollson PartyRed 13 1003 2002 Tollson PartyRed
解决方案
核心思路是先按行政区分组,确定每个行政区的有效年份范围(从首次出现的年份到2004年),再在组内补全年份并填充信息,避免跨组填充无效数据。
方法一:dplyr + tidyr 分组处理
library(dplyr) library(tidyr) df_clean <- df |> # 按行政区分组 group_by(district) |> # 生成当前行政区的有效年份序列:从组内最小年份到2004年 complete(year = seq(min(year), 2004, by = 1)) |> # 组内向下填充行政长官和政党信息 fill(executive.name, party, .direction = "down") |> # 取消分组 ungroup() # 查看结果 print(df_clean)
方法二:data.table 高效处理(适合大数据)
如果数据量较大,用data.table更高效:
library(data.table) setDT(df) df_clean <- df[, .(year = seq(min(year), 2004, by = 1)), by = district] |> merge(df, by = c("district", "year"), all.x = TRUE) |> setorder(district, year) |> .[, `:=`(executive.name = nafill(executive.name, type = "locf"), party = nafill(party, type = "locf")), by = district] # 查看结果 print(df_clean)
结果验证
两种方法都会得到符合预期的面板数据,1003号行政区仅保留2003-2004年的有效数据,没有无效填充的行。
内容的提问来源于stack exchange,提问作者YouLocalRUser
相关产品推荐
相关产品推荐

