如何在R语言中对多列执行滑动z-score标准化函数?
问题分析与解决
原代码存在几个核心问题导致结果不符合预期:
scale(x)默认不忽略NA值,窗口中存在NA时会直接返回NA;scale(x)返回矩阵结构,当窗口大小小于8时,会返回与窗口长度一致的向量,和rollapply预期的单值输出不匹配;- 多余的
by.column=TRUE参数在处理单个向量时无效; - 未处理标准差为0的边界情况,会触发除以0错误。
以下是修正后的代码,满足窗口逐步增大至8、忽略NA值、计算滑动窗口z-score的需求:
library(zoo) library(dplyr) # 生成带NA的测试数据 set.seed(123) df <- as.data.frame( matrix(round(runif(n = 120, min = 1, max = 20), 0), nrow = 20) ) df[sample(1:20, 3), sample(1:6, 2)] <- NA # 自定义z-score计算函数:忽略NA,返回窗口最后一个元素的z-score z_score <- function(x) { mu <- mean(x, na.rm = TRUE) sigma <- sd(x, na.rm = TRUE) # 处理标准差为0的情况(避免除以0) if (sigma == 0) { return(0) } # 计算窗口最后一个元素的z-score,保留两位小数 round((tail(x, 1) - mu) / sigma, 2) } # 对每列应用滑动窗口z-score计算 df_scaled <- df %>% mutate(across( 1:6, ~rollapply( .x, width = 8, FUN = z_score, partial = TRUE, # 允许窗口逐步增大至8 align = "right", # 窗口对齐方式:每个结果对应窗口右端位置 fill = NA # 无有效窗口的位置填充NA(可选) ) ))
关键说明
partial=TRUE:让前7个位置的窗口大小从1逐步增加到7,第8个位置开始固定为8个观测值;- 自定义
z_score函数:手动计算均值和标准差时通过na.rm=TRUE忽略NA,同时处理标准差为0的边界情况; align="right":确保每个窗口的计算结果对应窗口的最后一个观测值,匹配数据框的行位置。
内容的提问来源于stack exchange,提问作者user13973103
相关产品推荐
相关产品推荐

