R语言:如何利用累计值插补连续缺失的日度观测值?
用累计值插补缺失日数据的实操方案
当然可以利用已知的准确累计值插补,这是比样条、SARIMA或神经网络更可靠的选择——毕竟真实的累计数据没有模型假设带来的误差,完全没必要舍近求远。
针对你的示例数据:
data <- data.frame(time=c(1:10), value=c(22,15,24,28,NA,NA,87,18,22,24))
这里time=7的87对应time=5和time=6两天的累计值,下面是具体的R实现步骤:
1. 定位缺失区间与对应累计值
先标记缺失位置,找到连续缺失的日期范围,再匹配后面的累计值:
# 标记缺失值 data$is_missing <- is.na(data$value) # 给连续缺失/非缺失的块分组 data$block <- cumsum(c(1, diff(data$is_missing) != 0)) # 提取所有连续缺失的块信息 missing_blocks <- aggregate(time ~ block, data = data[data$is_missing, ], FUN = function(x) c(start = min(x), end = max(x))) missing_blocks$start_time <- missing_blocks$time[,1] missing_blocks$end_time <- missing_blocks$time[,2] missing_blocks$time <- NULL # 匹配每个缺失块对应的累计值(就是缺失块结束后的第一个非缺失值) missing_blocks$total <- sapply(missing_blocks$end_time, function(x) data$value[x+1])
2. 拆分累计值到缺失日期
因为你提到连续两日数值相同的情况极少,这里先按均分处理(如果有历史数据,也可以按前几日的数值比例拆分,更贴合实际):
# 计算每日插补值:累计值 / 缺失天数 missing_blocks$daily_val <- missing_blocks$total / (missing_blocks$end_time - missing_blocks$start_time + 1) # 将插补值填回原数据 for(i in 1:nrow(missing_blocks)){ data$value[data$time >= missing_blocks$start_time[i] & data$time <= missing_blocks$end_time[i]] <- missing_blocks$daily_val[i] } # 清理辅助列 data <- data[, !names(data) %in% c("is_missing", "block")]
运行后,time=5和time=6的value会被设为43.5,符合你的数据需求。
关于其他方案的说明
- 只有当你没有准确累计值可用时,才考虑样条插值、SARIMA或神经网络这类方法——这些方法依赖数据规律的假设,误差必然比用真实累计值插补大。
- 绝对不建议删除该观测值,你手里的累计值是有效信息,删除只会损失数据质量。
内容的提问来源于stack exchange,提问作者wernor
相关产品推荐
相关产品推荐

