Base R为数据框新增带NA处理的分组5期移动和指标列
纯Base R实现分组滚动有效观测指标计算
实现逻辑说明
- 先为原始数据标记原始行号,计算完成后可还原任意乱序的原始数据排列
- 自动按
Country字段分组,组内按date字段升序排列,保证时序正确性 - 逐行匹配当前行日期之前的历史观测,自动过滤
Value1为NA的无效记录,追溯最近的5个有效Value1值求和 - 凑够5个有效观测时,按规则
(5个有效Value1之和 / 当前行Value2) * 100计算指标,不足5个有效观测时指标返回NA - 全程仅使用R基础包函数,无第三方依赖
完整实现代码
# 示例测试数据生成 set.seed(1) Country <- c(rep("USA", 10),rep("UK", 10), rep("China", 10)) Value1 <- sample(x = c(120, 340, 423), size = 30, replace = TRUE) Value2 <- sample(x = c(1,3,5,6,9), size = 30, replace = TRUE) date <- seq(as.POSIXct('2020/01/01'), as.POSIXct('2020/01/30'), by = "1 day") df = data.frame(Country, Value1, Value2, date) # 核心计算逻辑 # 标记原始行号,用于最后还原原始数据顺序 df$raw_row_id <- seq_len(nrow(df)) # 按国家、日期升序排序,保证分组时序正确 sorted_df <- df[order(df$Country, df$date), ] # 按国家拆分数据为分组列表 country_groups <- split(sorted_df, sorted_df$Country) # 定义单国家分组的指标计算函数 calc_group_indicator <- function(group_data) { # 初始化指标列,默认值为NA group_data$indicator <- NA_real_ group_n <- nrow(group_data) # 逐行计算指标 for (row_idx in seq_len(group_n)) { # 筛选当前行日期之前的所有历史观测 history_obs <- group_data[group_data$date < group_data$date[row_idx], ] # 过滤掉Value1为NA的无效观测,提取有效Value1序列 valid_value1 <- history_obs$Value1[!is.na(history_obs$Value1)] # 有效观测数≥5时才计算指标 if (length(valid_value1) >= 5) { # 取最近的5个有效观测求和 last5_sum <- sum(tail(valid_value1, 5)) # 按公式计算,当前行Value2为NA时自动返回NA group_data$indicator[row_idx] <- (last5_sum / group_data$Value2[row_idx]) * 100 } } return(group_data) } # 对所有国家分组批量计算 calculated_list <- lapply(country_groups, calc_group_indicator) # 合并所有分组计算结果 calculated_all <- do.call(rbind, calculated_list) # 按原始行号排序,还原原始数据的行顺序 final_df <- calculated_all[order(calculated_all$raw_row_id), ] # 移除临时使用的原始行号字段 final_df$raw_row_id <- NULL # 查看计算结果 head(final_df, 10)
逻辑验证说明
可手动插入NA值测试跳过逻辑,例如在示例数据中执行df$Value1[c(4, 15, 27)] <- NA后重新运行计算代码,会发现计算时自动跳过这些NA行,向前补足5个有效Value1再计算,完全匹配规则要求。如果需要调整有效观测窗口期长度、增加当前行值有效性判断,直接修改对应判断逻辑和tail取数参数即可。
内容的提问来源于stack exchange,提问作者Geek_Nerdy93
相关产品推荐
相关产品推荐

