如何使用rollapply函数查找局部极小值?——居中滚动窗口x轴偏移问题咨询
解决滚动窗口找局部极小值时的X轴偏移问题
我来帮你分析下代码里的问题,以及如何修复这个偏移:
问题根源
你的代码里有两个关键问题导致了X轴偏移:
混淆了Zoo索引和数据行索引
你用index(rxz)[coredata(rxz)]获取的是X轴的数值(比如0.9、1.0这类),但随后把这些数值直接作为my.df的行索引使用。在R中,用数值作为数据框的索引时,会被自动取整当作位置索引(比如0.9会被当成第1行,对应X=0.1),这直接导致了偏移。错误的局部极小值判断逻辑
你设置的窗口宽度是20(偶数),并且判断which.min(x)==2——这是在检查窗口内第2个元素是否为最小值,完全不是找局部极小值的逻辑。再加上偶数宽度的居中窗口没有明确的中心位置,进一步加剧了偏移问题。
修复后的代码
我们用奇数宽度的滚动窗口(比如21,这样窗口有明确的中心位置),直接判断窗口中心是否为局部最小值,同时正确获取行索引:
require(ggplot2) require(zoo) # 生成原始数据 x <- seq(0, 25, by=0.1) y <- sin(x) my.df <- data.frame(x, y) # 选择奇数窗口宽度(确保有明确的中心) window_width <- 21 center_pos <- (window_width + 1) / 2 # 窗口内的中心位置,这里是第11个元素 # 滚动判断每个窗口的中心是否为最小值 is_local_min <- rollapply( y, width = window_width, align = "center", FUN = function(window) which.min(window) == center_pos ) # 获取局部极小值对应的行索引(自动忽略边缘的NA值) local_min_rows <- which(is_local_min) # 绘制结果,垂直虚线对应局部极小值的X位置 ggplot(my.df, aes(x, y)) + geom_line(linewidth = 0.8) + geom_vline( xintercept = my.df$x[local_min_rows], color = "firebrick", linetype = "dashed" )
代码说明
- 奇数窗口宽度:确保窗口有一个明确的中心位置,这样我们可以准确判断该中心是否为局部极小值(比窗口内其他所有点都小)。
- 正确获取行索引:用
which(is_local_min)直接得到原数据框中符合条件的行号,再通过my.df$x[local_min_rows]获取对应的X轴数值,避免了索引混淆。 - 逻辑清晰:判断窗口中心是否为最小值,完美匹配“局部极小值”的定义——该点在一定范围内是最小的。
如果你一定要使用偶数宽度的窗口,需要明确窗口内对应原数据的位置,调整判断的位置(比如判断窗口内第10或11个元素是否为最小值),但奇数窗口的方式更直观且不易出错。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

