如何用highcharter绘制stl对象?数据提取遇问题求方案
用highcharter绘制STL分解结果的解决方案
我想用{highcharter}绘制STL分解的结果,需要从stl对象中提取seasonal、trend、remainder这三个分量的数据。我的stl对象fit_stl结构如下:
str(fit_stl) #> List of 8 #> $ time.series: Time-Series [1:164, 1:3] from 2010 to 2024: 284.6 48.7 156.2 -78.8 -85 ... #> ..- attr(*, "dimnames")=List of 2 #> .. ..$ : NULL #> .. ..$ : chr [1:3] "seasonal" "trend" "remainder" #> $ weights : num [1:164] 1 1 1 1 1 1 1 1 1 1 ... #> $ call : language stl(x = TotalGen_ts, s.window = 10) #> $ win : Named num [1:3] 10 23 13 #> ..- attr(*, "names")= chr [1:3] "s" "t" "l" #> $ deg : Named int [1:3] 0 1 1 #> ..- attr(*, "names")= chr [1:3] "s" "t" "l" #> $ jump : Named num [1:3] 1 3 2 #> ..- attr(*, "names")= chr [1:3] "s" "t" "l" #> $ inner : int 2 #> $ outer : int 0 #> - attr(*, "class")= chr "stl"
用base R的plot函数可以直接绘制stl对象:
fit_stl = stl(TotalGen_ts, s.window = 10) plot(fit_stl)
但highcharter::hchart暂不支持直接传入stl对象,我尝试了两种提取数据的方法都失败:
第一种方法:
do.call(rbind.data.frame, fit_stl)
报错:
error: invalid list argument: all variables should have the same length
第二种方法:
df <- data.frame(matrix(unlist(fit_stl), nrow=length(fit_stl), byrow=TRUE))
出现警告:
Warning message:
In matrix(unlist(fit_stl), nrow = length(fit_stl), byrow = TRUE) :
data length [668] is not a sub-multiple or multiple of the number of rows [8]
可行解决方案
stl对象的time.series元素已经包含了我们需要的三个分量(seasonal、trend、remainder),它本身是带时间索引的矩阵格式,直接转换为数据框并保留时间信息即可,无需处理整个stl对象。
步骤1:提取并转换数据
# 提取time.series并转为数据框,同时添加时间列 stl_df <- as.data.frame(fit_stl$time.series) stl_df$date <- time(fit_stl$time.series)
步骤2:转成长格式(可选,更适合批量绘图)
如果需要一次性绘制三个系列,转成长格式会更方便:
library(tidyr) stl_long <- pivot_longer(stl_df, cols = c(seasonal, trend, remainder), names_to = "component", values_to = "value")
步骤3:用highcharter绘制
方法一:基于长格式数据批量绘制
library(highcharter) hchart(stl_long, "line", hcaes(x = date, y = value, group = component)) %>% hc_title(text = "STL分解结果") %>% hc_xAxis(title = list(text = "日期")) %>% hc_yAxis(title = list(text = "数值"))
方法二:逐个添加系列
如果不想转换数据格式,也可以手动逐个添加系列:
highchart() %>% hc_add_series(data = stl_df, type = "line", hcaes(x = date, y = seasonal), name = "季节性分量") %>% hc_add_series(data = stl_df, type = "line", hcaes(x = date, y = trend), name = "趋势分量") %>% hc_add_series(data = stl_df, type = "line", hcaes(x = date, y = remainder), name = "残差") %>% hc_title(text = "STL分解结果")
内容的提问来源于stack exchange,提问作者Magnetar
相关产品推荐
相关产品推荐

