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(对应一年周期)
常见疑问解答
日度vs月度频率选择:
- 日度数据:
frequency=365(或365.25适配闰年),但噪声大,模型拟合难度高,适合精细短期预测 - 月度数据:更平稳,适合中长期趋势预测,聚合后数据量适中,模型稳定性更好,也是你优先选择的方案
- 日度数据:
原代码无法运行的原因:
ts()函数语法错误:start参数嵌套了min和max,正确写法是start与end分开指定(或仅指定start)- 变量名错误:出现无关变量
gdpmodel、gdptime,应统一用asb相关变量名 - 缺少闭合括号:
class(未闭合,导致语法报错
内容的提问来源于stack exchange,提问作者Martin Holloway
相关产品推荐
相关产品推荐

