基于tsibble的每日温度时间序列STL分解参数与格式问题求助
解决每日温度数据STL分解问题
问题根源
你的代码存在两个核心问题:
- 未指定正确的时间序列频率:STL分解依赖明确的周期信息,每日温度数据的年周期为365天(考虑闰年可设为365.25),但直接对tsibble调用
stl时,程序无法自动识别该频率,导致季节成分计算完全失真。 - 参数设置不合理:
s.window = "periodic"会强制季节成分固定不变,不符合温度季节逐年略有波动的特性;同时未设置趋势窗口t.window,默认值过小导致趋势线不够平滑。
修正后的代码
library(tidyverse) library(rdwd) library(tsibble) library(fabletools) # 用于tsibble的时间序列分解 # 读取并预处理数据 df <- readDWD(dataDWD( selectDWD( name = "Jena (Sternwarte)", res = "daily", var = "kl", per = "historical" ), read = FALSE ), varnames = TRUE) %>% as_tibble() %>% mutate(MESS_DATUM = as.Date(MESS_DATUM)) %>% filter(MESS_DATUM >= as.Date("2005-01-01")) %>% rename(Temperatur = TMK.Lufttemperatur) %>% # 处理缺失值(STL分解不允许缺失值) fill(Temperatur, .direction = "downup") %>% # 转换为tsibble并确保时间序列连续 as_tsibble(index = MESS_DATUM) %>% fill_gaps() # 使用fabletools的STL分解,指定正确的周期和参数 decomp <- df %>% model(STL(Temperatur ~ trend(window = 1095) + season(window = 365), robust = TRUE)) %>% components() # 绘制分解结果 autoplot(decomp)
参数说明
trend(window = 1095):设置趋势窗口为1095天(约3年),窗口数值越大,趋势线越平滑,可根据需求调整。season(window = 365):指定季节周期为365天,匹配每日温度的年季节特性,替换原有的"periodic"参数,允许季节成分逐年微调。robust = TRUE:保持原设置,增强分解对异常值的鲁棒性。- 缺失值处理:通过
fill()和fill_gaps()确保时间序列无缺失,这是STL分解的必要前提。
替代方案(直接使用ts对象)
如果你习惯用基础包的stl函数,也可以将数据转换为ts对象后处理:
# 转换为ts对象,指定频率为365 ts_data <- ts(df$Temperatur, start = c(2005, 1), frequency = 365) # STL分解 stl_decomp <- stl(ts_data, s.window = 365, t.window = 1095, robust = TRUE) # 绘图 plot(stl_decomp)
内容的提问来源于stack exchange,提问作者TobKel
相关产品推荐
相关产品推荐

