R语言进行时间序列分析和预测

2023-09-25 14:13:13 浏览数 (1)

代码语言:javascript复制
library(tidyverse)
library(stringr)
library(janitor)
library(tsibble)
library(ggtext)
library(bsts)
library(tidybayes)
library(ggfx)

导入数据

代码语言:javascript复制
data <- readr::read_csv("data.txt")

数据清洗

代码语言:javascript复制
df <- data %>%
  clean_names() %>%    # 清理列名
  mutate(date = ymd(date)) %>%  # 将date列转换为日期格式
  rename(avg_price = apu000072610) %>% 
  filter(date > "2006-12-01") %>%    # 过滤出日期大于2006-12-01的数据
  mutate(avg_price = as.numeric(avg_price)) %>% 
  # 提取年、月、日信息
  mutate(year = year(date), month = month(date), day = day(date)) %>%
  # 将日期向下取整到月
  mutate(date = floor_date(as_date(date), "month")) %>% 
  # 将日期转换为年月格式
  mutate(date = yearmonth(date))

构建预测数据

❝用bsts函数对avg_price进行拟合和预测。bsts包是用于Bayesian structural time series模型的R包,它可以用于时间序列数据的分析和预测。 ❞

代码语言:javascript复制
set.seed(1234) # 设置随机种子
# 添加局部线性趋势
ss <- AddLocalLinearTrend(list(), df$avg_price)
ss <- AddSeasonal(ss, df$avg_price, nseasons = 12) # 添加季节性
# 使用bsts函数拟合模型
model <- bsts(df$avg_price, state.specification = ss, niter = 1000)
horizon <- 48 # 设置预测的时间范围

# 创建预测数据框
df_forecast <- data.frame(date = max(df$date)   1:horizon) %>% 
  # 添加预测值
  add_draws(predict(model, horizon = horizon, burn = SuggestBurn(0.1, model), 
                    quantiles = c(0.25, 0.75))$distribution) %>% =
  sample_draws(200)   # 随机抽取1000个样本

数据可视化

代码语言:javascript复制
ggplot()  
  # 添加原始数据的线条图层
  geom_line(data = df, aes(x = as.Date(date), y = avg_price), color = "#FFFFFF", linewidth = 0.8)  
  # 使用外发光效果添加预测数据的线条图层
  with_outer_glow(
    geom_line(data = df_forecast, aes(x = as.Date(date), y = .value, group = .draw), 
              linewidth = 0.3, color = "#69F0AE", alpha = 0.5),
    color = "#69F0AE", sigma = 7)  
  # 设置y轴的范围和刻度
  scale_y_continuous(limits = c(0, NA), breaks = seq(0, 0.3, by = 0.04))  
  # 设置x轴的日期格式和刻度
  scale_x_date(date_breaks = "2 years", date_labels = "%Y")  
  # 使用最小主题
  theme_minimal()  
  # 设置图例、轴文本、轴标题、轴线、网格线和图背景的样式
  theme(legend.position = "none",
        axis.text = element_text(size = 8,color = "black"),
        axis.title.y = element_text(size = 8,color = "black", margin  = margin(r = 5)),
        axis.title.x = element_text(size = 8,color = "black", margin = margin(t = 20)),
        axis.line = element_line(color = "black", linewidth = 0.3),
        panel.grid = element_line(color = "#616161", linewidth = 0.2, linetype = "dashed"),
        plot.margin = unit(c(1, 1, 1, 1), "cm"),
        plot.background = element_rect(color = NA, fill = "grey80")) 

0 人点赞