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

R语言数据框转时间序列对象的技术求助及代码修正

问题概述

我有3年的每日数据,需要用R代码把数据框转成时间序列对象,但对写法存疑:

  • 纠结频率设为月度还是日度,要不要调整原始数据适配R
  • 原代码无法运行,改成年度频率(frequency=1)能跑但丢了很多信息
  • 对auto.arima、forecast参数和残差处理的代码有疑问
  • 想要月度优先的预测方案,求正确实现方法

原始数据片段

Submitted   Count of Submitted
01/03/2019  1
02/03/2019  0
03/03/2019  0
04/03/2019  0
05/03/2019  1
06/03/2019  0
07/03/2019  1
08/03/2019  2
09/03/2019  0
10/03/2019  0
11/03/2019  27
12/03/2019  54
13/03/2019  52
14/03/2019  46
15/03/2019  44

问题代码

install.packages("readxl")
install.packages("forecast")
install.packages("tseries")

library(readxl)
library(forecast)
library(tseries)
asb <- read_excel("C://Users//BCCAMNHY//OneDrive - Birmingham City Council//HomeFiles//My Documents//DATA ANALYST TRAINING//PROJECT 4//PROJECT DOCUMENTS//ASB_311022.xlsx")

View(asb)
class(
asbtime=ts(asb$`ASB Submitted`,start = min(asb$`Date for R`,end = max(asb$`Date for R`),frequency = 12)
class(asbtime)
library(forecast)
library(tseries)
plot(asbtime)
acf(asbtime)
pacf(asbtime)
adf.test(asbtime)
gdpmodel=auto.arima(gdptime,ic="aic",trace = TRUE) ## dont understand this line of code
acf(ts(asb$residuals)) # not sure if this code should be changed to asb$asb submitted
pacf(ts(asb$residuals))# as above
myasbforecast=forecast(asbmodel,level = c(95),h=10*4) ##### Don't understand this line of code. Want a monthly or daily forecast - think ideally monthly
mygdpforecast
plot(asbforecast)
Box.test(myasbforecast$resid, lag=5, type= "Ljung-Box")
Box.test(mygdpforecast$resid, lag=15, type= "Ljung-Box")
Box.test(myasbforecast$resid, lag=25, type= "Ljung-Box")

解决方案(月度预测优先)

1. 数据预处理:日数据转月度汇总

优先做月度预测的话,先把每日数据按月份聚合,计算每月总提交量,减少噪声干扰,让数据更适合时间序列分析:

# 加载必要包
library(readxl)
library(dplyr)
library(lubridate)
library(forecast)
library(tseries)

# 读取数据
asb <- read_excel("C://Users//BCCAMNHY//OneDrive - Birmingham City Council//HomeFiles//My Documents//DATA ANALYST TRAINING//PROJECT 4//PROJECT DOCUMENTS//ASB_311022.xlsx")

# 转换日期格式并提取年月分组
asb <- asb %>%
  mutate(Submitted = dmy(Submitted),  # 将字符型日期转为标准日期格式
         year_month = floor_date(Submitted, "month"))  # 按月份分组

# 月度汇总:计算每月总提交数
monthly_asb <- asb %>%
  group_by(year_month) %>%
  summarise(total_submitted = sum(`Count of Submitted`)) %>%
  ungroup()

2. 转换为月度时间序列对象

月度数据的frequency设为12(一年12个月),start参数指定数据起始的年和月:

# 创建月度时间序列
asb_ts <- ts(monthly_asb$total_submitted,
             start = c(year(min(monthly_asb$year_month)), month(min(monthly_asb$year_month))),
             frequency = 12)

# 查看时间序列结构并可视化
class(asb_ts)
plot(asb_ts)  # 直观查看月度趋势

3. 模型构建与参数解释

auto.arima()参数说明

auto.arima()会自动筛选最优ARIMA模型:

  • ic="aic":用AIC准则(赤池信息准则)选模型,值越小模型越优
  • trace=TRUE:输出模型筛选过程,方便查看评估过的模型

修正后的代码:

# 自动选择最优ARIMA模型
asb_model <- auto.arima(asb_ts, ic = "aic", trace = TRUE)
summary(asb_model)  # 查看模型详细信息

4. 预测与参数解释

forecast()参数说明

forecast()用于生成预测结果:

  • level=c(95):生成95%置信区间的预测值
  • h:预测期数,比如预测未来12个月就设h=12

修正后的代码:

# 生成未来12个月的月度预测
asb_forecast <- forecast(asb_model, level = c(95), h = 12)

# 可视化预测结果
plot(asb_forecast)

5. 残差检验修正

残差是模型预测值与实际值的差值,检验残差是否为白噪声(无自相关)是判断模型有效性的关键,正确提取残差的方式是从训练好的模型中获取:

# 提取模型残差
residuals <- residuals(asb_model)

# 绘制残差的ACF/PACF图,检查自相关性
acf(residuals)
pacf(residuals)

# Ljung-Box检验:p值>0.05则说明残差是白噪声,模型拟合良好
Box.test(residuals, lag = 12, type = "Ljung-Box")  # 月度数据建议lag设为12(对应一年周期)

常见疑问解答

  1. 日度vs月度频率选择:

    • 日度数据:frequency=365(或365.25适配闰年),但噪声大,模型拟合难度高,适合精细短期预测
    • 月度数据:更平稳,适合中长期趋势预测,聚合后数据量适中,模型稳定性更好,也是你优先选择的方案
  2. 原代码无法运行的原因:

    • ts()函数语法错误:start参数嵌套了min和max,正确写法是start与end分开指定(或仅指定start)
    • 变量名错误:出现无关变量gdpmodel、gdptime,应统一用asb相关变量名
    • 缺少闭合括号:class(未闭合,导致语法报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 00:31:04