R中的每周和每年季节性

时间:2018-12-25 13:46:19

标签: r time-series

我有2007年1月1日至2016年12月31日的每日电力负荷数据。我使用ts()函数像这样加载数据

ts_load <- ts(data, start = c(2007,1), end = c(2016,12),frequency = 365)

我想从数据中删除每年和每周的季节性,以分解数据并删除季节性,我使用以下代码

decompose_load = decompose(ts_load, "additive")
deseasonalized = ts_load - decompose_load$seasonal

我的问题是,我做对了吗?这是消除年度季节性的正确方法吗?删除每周季节性的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

几点:

  • ts系列必须具有规则间隔的点,并且每个循环中的点数均相同。该问题的频率指定为365,但某些年份(即leap年)将获得366分。特别是,如果您希望频率为一年,那么您就无法使用每日或每周数据而无需进行调整,因为不同的年份有不同的天数,并且一年中的周数不是整数。

  • decompose无法处理多个季节。如果按周表示消除星期一,星期二等的影响,如果按年表示消除是1月1日,2月等的影响,则您要求多个季节。

  • end = c(2017, 12)表示频率为365,因此是2017年的第12天。

预测包中的msts函数可以处理多个和非整数的季节性。

与基数R保持相同,另一种方法是通过线性模型对其进行近似,从而避免上述所有问题(但忽略相关性),我们将对此进行讨论。

假定末尾注释中的数据可重复显示,我们定义星期几dow和一年中的doy,对具有截距和趋势的变量进行变量和回归,然后在最后一行代码中构造截距加趋势加残差以进行反季节化。这不是绝对必要的,但是为了使定义scale的三个术语相互正交,我们已经使用trend去除了data.ds的均值-无论我们是否在第三个线性模型的性质将使该术语与其他2个正交。

trend <- scale(seq_along(d), TRUE, FALSE)
dow <- format(d, "%a")
doy <- format(d, "%j")
fm <- lm(data ~ trend + dow + doy)
data.ds <- coef(fm)[1] + coef(fm)[2] * trend + resid(fm)

注意

以可复制形式使用的测试数据:

set.seed(123)
d <- seq(as.Date("2007-01-01"), as.Date("2016-12-31"), "day")
n <- length(d)
trend <- 1:n
seas_week <- rep(1:7, length = n)
seas_year <- rep(1:365, length = n)
noise <- rnorm(n)
data <- trend + seas_week + seas_year + noise

答案 1 :(得分:0)

您可以使用dsa软件包中的dsa功能来调整每日时间序列。与回归解决方案相比的优势在于,它考虑到了季节的影响会随时间变化的情况(通常是这种情况)。 为了使用该功能,您的数据应为xts格式(来自xts包)。因为在那种情况下the年不会被忽略。 然后,代码将如下所示:

install.packages(c("xts", "dsa"))

data = rnorm(365.25*10, 100, 1)
data_xts <- xts::xts(data, seq.Date(as.Date("2007-01-01"), by="days", length.out = length(data)))

sa = dsa::dsa(data_xts, fourier_number = 24) 
# the fourier_number is used to model monthly recurring seasonal patterns in the regARIMA part

data_adjusted <- sa$output[,1]