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

含缺失值面板数据:最大化连续年份或国家数量的编码实现

面板数据平衡筛选:两种核心策略的R实现

我有一份覆盖15年的国家面板数据,存在缺失值,需要编写R代码实现两种平衡面板筛选策略:

  • 策略一:以减少连续观测年份为代价,最大化观测国家数量
  • 策略二:以减少观测国家数量为代价,最大化连续观测年份

示例数据场景说明

  • 最大化连续年份:可得到2002-2003年共2年、6个国家(Country1、Country2、Country4、Country5、Country7、Country8)的数据集
  • 最大化国家数量:可选2003年(仅缺失Country3)或2005年(仅缺失Country2),均可得到9个国家、1年的数据集

示例面板数据

df <- structure(list(country = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 
5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 
8L, 8L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L), levels = c("Country1", 
"Country2", "Country3", "Country4", "Country5", "Country6", "Country7", 
"Country8", "Country9", "Country10"), class = "factor"), year = c(2001L, 
2002L, 2003L, 2004L, 2005L, 2001L, 2002L, 2003L, 2004L, 2005L, 
2001L, 2002L, 2003L, 2004L, 2005L, 2001L, 2002L, 2003L, 2004L, 2005L, 
2001L, 2002L, 2003L, 2004L, 2005L, 2001L, 2002L, 2003L, 2004L, 2005L, 
2001L, 2002L, 2003L, 2004L, 2005L, 2001L, 2002L, 2003L, 2004L, 2005L, 
2001L, 2002L, 2003L, 2004L, 2005L, 2001L, 2002L, 2003L, 2004L, 2005L), 
x = c(NA, 0.494188331267827, -0.681660478755657, -0.652094780680999, -1.28630053043433, 
1.68217608051942, -0.177330482269606, -0.324270272246319, -0.0568967778473925, NA, 
-0.635736453948977, -0.505957462114257, NA, NA, 0.450187101272656, 
-0.461644730360566, 1.34303882517041, -0.588894486259664, NA, -0.018559832714638, 
NA, -0.214579408546869, 0.531496192632572, NA, -0.318068374543844, 
-0.508055079939179, NA, -1.51839408178679, -0.463530401472386, -0.929362147453702, 
NA, -0.100190741213562, 0.306557860789766, NA, -1.48746031014148, NA, 
0.712666307051405, -1.53644982353759, NA, -1.07519229661568, -0.319992868548507, 
NA, -0.300976126836611, NA, 1.00002880371391, NA, NA, -0.528279904445006, 
0.0173956196932517, -0.621266694796823)), out.attrs = list(dim = c(country = 10L, 
year = 5L), dimnames = list(country = c("country=Country1", "country=Country2", 
"country=Country3", "country=Country4", "country=Country5", "country=Country6", 
"country=Country7", "country=Country8", "country=Country9", "country=Country10"
), year = c("year=2001", "year=2002", "year=2003", "year=2004", "year=2005"))), 
row.names = c(NA, -50L), class = "data.frame")

# 可视化缺失值分布
library(panelView)
panelview(data = df, Y = "x", type = "missing", index = c("country", "year"))

策略一:最大化观测国家数量

逻辑

统计每个年份中拥有非缺失值的国家数量,筛选出国家数量最多的年份(若多个年份数量相同,全部保留),得到对应年份的所有非缺失数据。

代码实现

library(dplyr)

# 1. 统计各年份的非缺失国家数
year_country_count <- df %>%
  filter(!is.na(x)) %>%
  group_by(year) %>%
  summarize(country_n = n_distinct(country)) %>%
  ungroup()

# 2. 找出最大的国家数量
max_country_n <- max(year_country_count$country_n)

# 3. 筛选对应年份的非缺失数据
balanced_max_countries <- df %>%
  filter(year %in% year_country_count$year[year_country_count$country_n == max_country_n],
         !is.na(x))

# 查看结果
balanced_max_countries %>%
  group_by(year) %>%
  summarize(country_count = n_distinct(country))

结果说明

运行后会得到国家数量最多的年份数据,示例中为2003年和2005年,各9个国家。


策略二:最大化连续观测年份

逻辑

  1. 对每个国家,找出所有连续的非缺失年份区间
  2. 枚举所有可能的连续年份区间,统计每个区间内全程无缺失的国家数量
  3. 优先选择长度最长的区间;若区间长度相同,选择覆盖国家最多的区间
  4. 筛选该区间内的所有国家数据

代码实现

# 1. 为每个国家生成连续非缺失年份的区间
country_continuous_intervals <- df %>%
  filter(!is.na(x)) %>%
  arrange(country, year) %>%
  group_by(country) %>%
  # 标记连续年份组:当前年份与前一年差1则同组,否则新组
  mutate(grp = cumsum(year != lag(year, default = first(year) - 1) + 1)) %>%
  group_by(country, grp) %>%
  summarize(start_year = min(year), end_year = max(year), .groups = "drop") %>%
  select(country, start_year, end_year)

# 2. 生成所有可能的连续年份区间(基于全局年份范围)
all_years <- sort(unique(df$year))
possible_intervals <- expand.grid(start = all_years, end = all_years) %>%
  filter(start <= end) %>%
  mutate(length = end - start + 1)

# 3. 统计每个区间内满足全程无缺失的国家数
interval_country_count <- possible_intervals %>%
  rowwise() %>%
  mutate(
    # 找出所有国家中,其连续区间完全包含当前区间的
    country_n = sum(
      country_continuous_intervals$start_year <= start & 
      country_continuous_intervals$end_year >= end
    )
  ) %>%
  ungroup()

# 4. 选出最优区间:先按长度降序,再按国家数降序
optimal_interval <- interval_country_count %>%
  arrange(desc(length), desc(country_n)) %>%
  slice(1)

# 5. 筛选对应区间和国家的数据
# 先找出符合条件的国家
qualified_countries <- country_continuous_intervals %>%
  filter(start_year <= optimal_interval$start & end_year >= optimal_interval$end) %>%
  pull(country)

# 再筛选数据
balanced_max_years <- df %>%
  filter(country %in% qualified_countries,
         year >= optimal_interval$start,
         year <= optimal_interval$end,
         !is.na(x))

# 查看结果
balanced_max_years %>%
  summarize(
    start_year = min(year),
    end_year = max(year),
    total_years = n_distinct(year),
    country_count = n_distinct(country)
  )

结果说明

示例中会得到2002-2003年的区间,覆盖6个国家,符合预期。


生成带缺失值的面板数据代码

set.seed(0) # 保证结果可复现

# 创建10个国家、5年的面板框架
countries <- paste("Country", 1:10, sep="")
years <- 2001:2005
df <- expand.grid(country = countries, year = years)

# 生成随机数据
df$x <- rnorm(nrow(df))

# 为每个国家随机引入1-2个缺失年份
for (country in countries) {
  missing_years_count <- sample(1:2, 1, replace = TRUE)
  missing_years <- sample(years, missing_years_count)
  df$x[df$country == country & df$year %in% missing_years] <- NA
}

# 排序数据
df <- df %>% arrange(country, year) 

# 可视化缺失值
panelview(data = df, Y = "x", type = "missing", index = c("country", "year"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:37:01