You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:47:00