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

如何在R语言时间序列图中添加loess拟合线?

解决R语言时间序列中添加loess拟合线的问题

别担心,我来帮你理清loess函数的公式参数,还会教你添加两条不同span的拟合线,一步步来:

核心知识点:loess的公式格式

loess函数的公式遵循因变量 ~ 自变量的格式,这里我们要拟合生猪屠宰数量随时间的变化趋势,所以:

  • 因变量:就是你的屠宰数量列(示例里是Total of Killed Pigs,真实数据里是那个长列名Monthly.total.number.of.pigs.slaughtered.in.Victoria..Jan.1980...August.1995)
  • 自变量:需要是连续的数值型时间变量(loess不能直接用字符型日期,所以我们可以生成一个时间索引,或者把日期转成数值)

先修正你的示例代码并实现拟合

你的示例数据里有个小错误:列名Monts拼写错了,应该是Months,先修正这个,然后添加时间索引,再拟合:

# 修正后的示例数据框(修正列名拼写)
table <- structure(
  list(
    Months = c("1980-06", "1980-07", "1980-08", "1980-09", "1980-10", "1980-11", "1980-12", "1981-01"),
    `Total of Killed Pigs` = c(75000, 70000, 60000, 73000, 72000, 71000, 76000, 71000)
  ),
  row.names = c(NA, 8L),
  class = "data.frame"
)

# 生成时间索引(连续数值,代表第几个时间点)
table$time_idx <- 1:nrow(table)

# 创建时间序列对象并绘图
ts.obj <- ts(table$`Total of Killed Pigs`, start = c(1980, 1), frequency = 12)
plot(ts.obj, main = "生猪屠宰数量时间序列 + loess拟合", ylab = "屠宰数量")

# 第一条loess拟合线(span=1,平滑度高)
trend1 <- loess(`Total of Killed Pigs` ~ time_idx, data = table, span = 1)
predict1 <- predict(trend1)
lines(predict1, col = "blue", lwd = 2)

# 第二条loess拟合线(span=0.5,更贴近原始数据)
trend2 <- loess(`Total of Killed Pigs` ~ time_idx, data = table, span = 0.5)
predict2 <- predict(trend2)
lines(predict2, col = "red", lwd = 2)

# 添加图例区分两条线
legend("topright", legend = c("span=1", "span=0.5"), col = c("blue", "red"), lwd = 2)

真实数据的完整代码

针对你下载的真实数据,代码逻辑是一样的,只需要调整列名:

# 读取数据(替换成你的文件路径)
obj <- read.csv(file="PATH/monthly-total-number-of-pigs-sla.csv", header=TRUE, sep=",")

# 生成时间索引
obj$time_idx <- 1:nrow(obj)

# 创建时间序列对象并绘图
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 = "维多利亚州生猪屠宰数量时间序列", ylab = "月度屠宰数量")

# 第一条loess拟合线(span=1)
trend1 <- loess(Monthly.total.number.of.pigs.slaughtered.in.Victoria..Jan.1980...August.1995 ~ time_idx, 
                data = obj, span = 1)
predict1 <- predict(trend1)
lines(predict1, col = "blue", lwd = 2)

# 第二条loess拟合线(span=0.3,更灵敏捕捉波动)
trend2 <- loess(Monthly.total.number.of.pigs.slaughtered.in.Victoria..Jan.1980...August.1995 ~ time_idx, 
                data = obj, span = 0.3)
predict2 <- predict(trend2)
lines(predict2, col = "red", lwd = 2)

# 添加图例
legend("topright", legend = c("span=1", "span=0.3"), col = c("blue", "red"), lwd = 2)

关键说明

  • span参数:控制拟合线的平滑程度,值越大线越平滑,值越小越贴近原始数据(通常在0.2到1之间调整)
  • 为什么用time_idx而不是日期?因为loess要求自变量是数值型,直接用日期的话需要先转成数值(比如as.numeric(as.Date(obj$Months))),但用连续索引更简单直观,对时间序列趋势拟合的效果是一样的
  • 如果列名有空格或特殊字符,记得用反引号`把列名包起来,避免报错

内容的提问来源于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:33:58