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

为长格式时间序列数据补全含NA的缺失行(优先dplyr方案)

如何用dplyr优雅地为长格式data.frame补全缺失的观测行?

首先先明确你的原始数据情况:

mydata <- data.frame(year = rep(c(2000,2001,2002,2004), 2), 
                     team = factor(c("A","A","A","A", "B","B","B","B")), 
                     score = c(8,1,3,1,2,3,7,2))

# 查看原始数据
mydata
#>   year team score
#> 1 2000    A     8
#> 2 2001    A     1
#> 3 2002    A     3
#> 4 2004    A     1
#> 5 2000    B     2
#> 6 2001    B     3
#> 7 2002    B     7
#> 8 2004    B     2

确实,2003年的观测对两个队都缺失了,需要补全这些行并将score填充为NA。

最优dplyr/tidyr方案:用complete()函数

complete()是tidyr包中的函数(属于tidyverse生态,和dplyr无缝配合),专门用来补全数据中缺失的组合,代码非常简洁:

# 先加载tidyverse包(包含dplyr和tidyr)
library(tidyverse)

# 补全缺失行
mydata_complete <- mydata %>%
  complete(year = full_seq(year, 1), team)

代码解释:

  • full_seq(year, 1):自动生成从year列最小值到最大值之间的所有连续整数,这里就是2000-2004的所有年份,解决了年份间隔缺失的问题;
  • team:直接指定这个变量,函数会自动包含它的所有因子水平(A和B),确保每个年份都和每个队组合;
  • 原来存在的行会保留score的原始值,缺失的组合会自动将score填充为NA。

如果想要和你目标数据完全一致的排序(先A队的所有年份,再B队的),只需要再加一步arrange():

mydata_complete <- mydata %>%
  complete(year = full_seq(year, 1), team) %>%
  arrange(team, year)

最终结果:

mydata_complete
#> # A tibble: 10 × 3
#>    year team  score
#>   <dbl> <fct> <dbl>
#> 1  2000 A         8
#> 2  2001 A         1
#> 3  2002 A         3
#> 4  2003 A        NA
#> 5  2004 A         1
#> 6  2000 B         2
#> 7  2001 B         3
#> 8  2002 B         7
#> 9  2003 B        NA
#>10  2004 B         2

补充:expand.grid + left_join方案

你提到的expand.grid也能解决,不过步骤稍多,需要先生成所有可能的组合再做连接:

# 生成所有年份和队的组合
all_combinations <- expand.grid(year = seq(min(mydata$year), max(mydata$year), 1),
                                team = levels(mydata$team))

# 左连接原始数据,补全缺失值
mydata_complete2 <- left_join(all_combinations, mydata, by = c("year", "team")) %>%
  arrange(team, year)

但显然complete()的方案更符合“优雅简洁”的要求,不需要手动生成组合,一步到位。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:05:16