R语言嵌套函数实现时序异常值检测报错求助
时序异常值检测函数错误修复
问题背景
尝试实现一种时序异常值检测算法,封装成可指定时序向量、窗口大小和阈值的函数,但运行时触发错误:
Error in zoo(do.call("c", dat), index(data)[ix], attr(data,"frequency")) : “x” : attempt to define invalid zoo object
示例数据
n.length <- 1150 cycle.a <- 11 cycle.b <- 365/12 amp.a <- 800 amp.b <- 8000 set.seed(17) x <- 1:n.length baseline <- (1/2) * amp.a * (1 + sin(x * 2*pi / cycle.a)) * rgamma(n.length, 40, scale=1/40) peaks <- rbinom(n.length, 1, exp(2*(-1 + sin(((1 + x/2)^(1/5) / (1 + n.length/2)^(1/5))*x * 2*pi / cycle.b))*cycle.b)) y <- peaks * rgamma(n.length, 20, scale=amp.b/20) + baseline
出错的函数代码
mad_function <- function(vec, threshold, window){ upper_thresh <- function(vec) { # CALCULATE THE MEDIAN OF THE WINDOW m <- median(vec) # CALCULATE THE MEDIAN ABSOLUTE DEVIATION median(vec) + threshold * median(abs(vec - m)) return(upper_thresh) } # CALCULATE THE MEAN ABSOLUTE DEVIATIONS FOR EACH ROLLING WINDOW mads <- rollapply(zoo(vec), window, upper_thresh, align = "right") # CONCATENATE THE FIRST VALUE OF THE MADs VECTOR TO THE MADs RESULT ABOVE DUE TO THE ROLLING WINDOW EFFECT mads <- c(rep(mads[1], window - 1), mads) # IDENTIFY IF POINTS ARE OUTLIERS OR INLIERS outliers <- vec > mads return(outliers) }
错误原因与修复方案
错误核心在于内部函数upper_thresh的返回逻辑错误:它返回的是函数自身upper_thresh,而非计算得到的阈值数值,导致rollapply无法生成有效的zoo对象。同时,内部函数参数名与外层函数的vec重名,易引发变量混淆。
修复后的函数代码:
mad_function <- function(vec, threshold, window){ upper_thresh <- function(window_vec) { # 计算窗口中位数 m <- median(window_vec) # 计算上阈值:中位数 + threshold*中位数绝对偏差 m + threshold * median(abs(window_vec - m)) } # 对zoo格式的时序数据应用滚动窗口计算阈值 mads <- rollapply(zoo(vec), window, upper_thresh, align = "right") # 补全滚动窗口起始阶段的阈值(用第一个窗口的阈值填充) mads <- c(rep(mads[1], window - 1), mads) # 判断每个点是否为异常值(超过上阈值) outliers <- vec > mads return(outliers) }
验证运行
确保先加载zoo包,再执行函数:
library(zoo) outlier_result <- mad_function(vec = y, threshold = 5, window = 30)
内容的提问来源于stack exchange,提问作者TheGoat
相关产品推荐
相关产品推荐

