R语言如何将参考期分组统计值匹配填充到全量数据集
问题场景
- 现有2000-2022年月度观测数据框
df,包含year(年份)、month(月份)字段,以及DKF、GDT、GSB三个项目的观测值,其中GDT字段2000-2001年取值为NaN。 - 需以2002-2021年为参考期计算长期统计指标,已通过如下代码生成长格式
LongTerm数据集,按project(项目)、month(月份)分组,计算得到每个项目各月的参考均值MeanRef、参考最小值MinRef、参考最大值MaxRef:
LongTerm <- df %>% filter(year %in% c(2002:2021))%>% gather(key = "project",value = "value", -c(year,month))%>% group_by(project,month)%>% mutate(MeanRef = mean(value,na.rm = T))%>% mutate(MinRef = min(value,na.rm = T))%>% mutate(MaxRef = max(value,na.rm = T))
- 目标是将三个参考值匹配到全量数据集所有记录,让2000、2001、2022年这些参考期外的记录,也能获取对应项目、对应月份的参考值。
- 之前的实现仅给2002-2021年的记录赋值了参考值,参考期外记录的参考值列均为NA,代码如下:
test <- df %>% gather(key = "project",value = "value", -c(year,month))%>% group_by(project,month)%>% mutate(MeanRef = NA)%>% mutate(MinRef = NA)%>% mutate(MaxRef = NA) test$MeanRef[which(test$year %in% c(2002:2021))] = LongTerm$MeanRef test$MinRef[which(test$year %in% c(2002:2021))] = LongTerm$MinRef test$MaxRef[which(test$year %in% c(2002:2021))] = LongTerm$MaxRef
说明:参考值是「项目+月份」维度的固定重复值,需要填充参考期外记录的NA完成全量匹配。
实现方案
之前按行位置直接赋值的方式容错性差,一旦数据排序变动、分组内行数不匹配就会出现错位,以下两种方式都可以稳定实现需求:
方法1:分组填充(基于现有test数据集补全)
同一project+month分组下的参考值是固定常量,直接在分组内取非NA的参考值填充所有空值即可,不需要重构数据集:
# 加载tidyverse包 library(tidyverse) # 保留之前生成test数据集、给参考期赋值的代码,新增以下填充逻辑 test <- test %>% group_by(project, month) %>% # 对三个参考值列,取分组内第一个非NA值覆盖所有行 mutate(across(c(MeanRef, MinRef, MaxRef), ~first(na.omit(.x)))) %>% ungroup()
该方法适用前提:同组内参考期计算出的参考值完全一致,和当前LongTerm数据集的聚合逻辑完全匹配。
方法2:提取映射表左连接(推荐,逻辑最稳妥)
不需要先生成空值再填充,直接从LongTerm中提取「项目-月份-参考值」的唯一映射表,和转成长格式的全量数据做关联匹配,一步到位,不会出现行错位问题:
library(tidyverse) # 第一步:提取参考值唯一映射表,每个project+month组合仅保留一行 ref_mapping <- LongTerm %>% select(project, month, MeanRef, MinRef, MaxRef) %>% distinct(project, month, .keep_all = TRUE) # 第二步:全量数据转长格式后,直接按project、month关联参考值 full_result <- df %>% gather(key = "project", value = "value", -c(year, month)) %>% left_join(ref_mapping, by = c("project", "month"))
该方法完全不依赖行顺序,匹配逻辑和观测值列无关,即使GDT列2000-2001年存在NaN也不会影响参考值匹配结果。
内容的提问来源于stack exchange,提问作者Haribo
相关产品推荐
相关产品推荐

