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

如何在R中为时间序列绘制上下平滑曲线?

给LOESS趋势线添加残差平滑上下包络线

嘿,我懂你要的效果了——不是调整LOESS的span参数,而是基于主LOESS曲线的残差,画出平滑的上下边界包络线对吧?下面是用基础R就能实现的简便方法,完全贴合你现有的代码逻辑:


第一步:先搞定主LOESS趋势和残差

先拟合你选定的那条主LOESS曲线,然后算出每个数据点和拟合值之间的残差:

# 用你的完整数据集代码为例
obj <- read.csv(file="PATH/monthly-total-number-of-pigs-sla.csv", header=TRUE, sep=",")
ts.obj <- ts(obj$Monthly.total.number.of.pigs.slaughtered.in.Victoria..Jan.1980...August.1995, start = c(1980, 1), frequency = 12)

# 先画出原始时间序列
plot(ts.obj, main = "Monthly Slaughtered Pigs: LOESS Trend + Residual Envelopes", col = "gray")

# 提取时间变量,方便后续拟合
time_vals <- as.numeric(time(ts.obj))

# 拟合主LOESS趋势(比如你用span=1的这条)
trend_main <- loess(ts.obj ~ time_vals, data = obj, span = 1)
fit_main <- predict(trend_main)

# 画出主LOESS曲线
lines(time_vals, fit_main, col = "darkblue", lwd = 2)

# 计算残差:原始值 - 拟合值
residuals <- ts.obj - fit_main

第二步:拟合残差的平滑上下边界

接下来,我们分别对正残差和负残差做LOESS平滑,这样就能得到贴合残差波动的上下包络线:

# 处理上边界:只保留正残差,再做LOESS平滑
upper_resid <- pmax(residuals, 0)
trend_upper <- loess(upper_resid ~ time_vals, span = 0.3)  # 这里的span控制平滑度,可按需调整
fit_upper <- fit_main + predict(trend_upper)

# 处理下边界:只保留负残差,再做LOESS平滑
lower_resid <- pmin(residuals, 0)
trend_lower <- loess(lower_resid ~ time_vals, span = 0.3)
fit_lower <- fit_main + predict(trend_lower)

第三步:画出上下包络线

最后把这两条平滑边界加到图上就行:

# 用虚线画出上下边界,和主LOESS曲线同色系
lines(time_vals, fit_upper, col = "darkblue", lty = 2)
lines(time_vals, fit_lower, col = "darkblue", lty = 2)

小提示

  • 残差LOESS的span参数是关键:值越大,包络线越平缓;值越小,越贴近残差的实际波动,你可以根据想要的效果微调。
  • 如果习惯用ggplot2,也可以用geom_smooth结合残差数据来实现,但上面的方法完全适配你现在用的基础绘图体系,不需要额外包。

内容的提问来源于stack exchange,提问作者Esinede1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:55:15