代码语言: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))
构建预测数据
代码语言:javascript复制❝用bsts函数对avg_price进行拟合和预测。bsts包是用于Bayesian structural time series模型的R包,它可以用于时间序列数据的分析和预测。 ❞
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"))