如何在R中按组用前5个前置值均值替换列内指定异常值?
修正后的dplyr代码实现
方案一:使用slider包实现滑动窗口均值
library(dplyr) library(slider) stock_data <- stock_data %>% group_by(gvkey) %>% # 标记需要替换的行:当前值为-1,或前一行值为-1 mutate(needs_replace = (ret_excess == -1) | lag(ret_excess == -1, default = FALSE)) %>% # 计算当前行前5个前置有效值(排除-1)的均值,不足5个则取现有全部 mutate(prev5_mean = slide_dbl( .x = ret_excess, .f = ~ mean(.x[.x != -1], na.rm = TRUE), .before = 5, .complete = FALSE )) %>% # 替换异常值和NA:异常值用前5均值,NA用组内非-1均值兜底 mutate(ret_excess2 = case_when( needs_replace ~ prev5_mean, is.na(ret_excess) ~ mean(ret_excess[ret_excess != -1], na.rm = TRUE), TRUE ~ ret_excess )) %>% # 移除辅助列并取消分组 select(-needs_replace, -prev5_mean) %>% ungroup()
方案二:使用zoo包的rollapply(无需额外安装slider)
library(dplyr) library(zoo) stock_data <- stock_data %>% group_by(gvkey) %>% mutate(needs_replace = (ret_excess == -1) | lag(ret_excess == -1, default = FALSE), # 滚动计算前1-5行的有效值均值 prev5_mean = rollapply( ret_excess, width = list(-(1:5)), FUN = function(x) mean(x[x != -1], na.rm = TRUE), fill = NA, align = "right" )) %>% # 处理前5行无有效值的情况,用组内非-1均值兜底 mutate(prev5_mean = ifelse(is.na(prev5_mean), mean(ret_excess[ret_excess != -1], na.rm = TRUE), prev5_mean), ret_excess2 = case_when( needs_replace ~ prev5_mean, is.na(ret_excess) ~ prev5_mean, TRUE ~ ret_excess )) %>% select(-needs_replace, -prev5_mean) %>% ungroup()
关键逻辑说明
- 先标记所有需要替换的行:包括值为
-1的行,以及它的下一行(对应高值异常) - 滑动窗口计算当前行之前最多5个非
-1的有效值均值,不足5个时自动取现有全部有效值计算 - 对NA值的处理保留了原需求的组内均值兜底,也可根据需要调整为前5均值
- 若组内所有值都是异常值,会用组内非
-1的均值(若全为-1则会返回NaN,可额外添加判断处理)
内容的提问来源于stack exchange,提问作者bernard202210
相关产品推荐
相关产品推荐

