R语言如何基于另一张表按分组扩展data.frame数据
R实现按分组补全周度序列方案
方法一:tidyverse实现(推荐,代码简洁易维护)
首先加载依赖包:
library(dplyr) library(tidyr)
步骤1:构造全量周度集合
把原数据已有的周度和待扩展的周度合并去重,得到完整的周列表:
all_weeks <- unique(c(df$range_key, extended_week$range_key))
注意:因为
range_key是w+两位周数+四位年份的字符串格式,直接做字符串排序/比较会出现跨年顺序错误(比如w522022会被判定为大于w012023),建议先做顺序校正:all_weeks <- tibble(range_key = all_weeks) %>% # 拼接为“年份+周数”的数值格式,方便正确排序 mutate(sort_id = as.numeric(sub("w(\\d{2})(\\d{4})", "\\2\\1", range_key))) %>% arrange(sort_id) %>% pull(range_key)
步骤2:按分组补全周度
根据你的业务需求二选一即可:
- 需求1:每个
(id, country, case)分组,覆盖从最早周(w232022)到w522026的全部周度
result <- df %>% complete(id, country, case, range_key = all_weeks) %>% # 按id、周度、case排序,方便查看 arrange(id, range_key, case)
- 需求2:每个
(id, country, case)分组,仅覆盖从该分组第一次出现的周到w522026的周度(比如case=B最早出现在w242022,就不需要补w232022的B记录)
result <- df %>% group_by(id, country, case) %>% # 记录每个分组最早出现的周 mutate(min_week = min(range_key)) %>% ungroup() %>% complete(id, country, case, range_key = all_weeks) %>% # 过滤掉分组出现前的无效周 filter(range_key >= min_week) %>% select(-min_week) %>% arrange(id, range_key, case)
小提示:如果原df除了4个核心字段还有其他指标字段,补全后缺失值如果需要按分组向前填充,可以在
complete后加group_by(id, country, case) %>% fill(everything(), .direction = "down")实现。
方法二:基础R实现(无需安装第三方包)
如果不想加载tidyverse,可以用基础R的合并功能实现,逻辑和上面一致:
# 1. 获取所有唯一的分组组合 unique_groups <- unique(df[, c("id", "country", "case")]) # 2. 构造全量周集合(需要做顺序校正可以参考上面的逻辑自行处理) all_weeks <- unique(c(df$range_key, extended_week$range_key)) # 3. 构造分组+周度的全量笛卡尔积 full_combination <- merge(unique_groups, data.frame(range_key = all_weeks), by = NULL) # 4. 和原数据左连接,保留原有记录 result <- merge( full_combination, df, by = c("id", "country", "case", "range_key"), all.x = TRUE ) # 5. 排序得到最终结果 result <- result[order(result$id, result$range_key, result$case), ]
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

