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

如何用data.table按id分组补全缺失年份并填充freq值为0?

完全可以用data.table实现,实现逻辑和你用dplyr分组合并的思路一致,而且语法更简洁,大数据量下执行效率更高。

实现代码

按每个id自身的起止年份补全(符合你的预期输出要求)

library(data.table)
# 你的示例数据
dt <- data.table(id=c('A','A','A','A','B','B','B','B'),year=c(2010,2012,2013,2015,2006,2007,2010,2011),freq=c(2,1,4,3,1,3,5,7))

# 核心实现逻辑
dt_full <- dt[, .(year = min(year):max(year)), by = id][
  dt, on = .(id, year), freq := i.freq
][
  is.na(freq), freq := 0
]

代码逻辑说明

  1. 第一步dt[, .(year = min(year):max(year)), by = id]:按id分组,为每个id生成从它自身最小记录年份到最大记录年份的连续年份序列,得到所有需要保留的id+year组合
  2. 第二步[dt, on = .(id, year), freq := i.freq]:和原始数据表按id、year字段左连接,把原始表中存在的freq值匹配到新的全量序列表中
  3. 第三步[is.na(freq), freq := 0]:把匹配不到的缺失年份的freq值统一替换为0

更简洁的写法(使用setnafill函数)

dt_full <- dt[, .(year = min(year):max(year)), by = id] |> 
  merge(dt, by = c("id", "year"), all.x = TRUE) |> 
  setnafill(cols = "freq", fill = 0)

扩展:按全局统一起止年份补全

如果你需要所有id都按照全表的最小年份和最大年份统一补全,用如下写法即可:

global_min_year <- dt[, min(year)]
global_max_year <- dt[, max(year)]
dt_full <- CJ(id = unique(dt$id), year = global_min_year:global_max_year)[
  dt, on = .(id, year), freq := i.freq
][
  is.na(freq), freq := 0
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:36:03