I have the following dataset (df) with 20 months:
price
2735.869
2857.105
2725.971
2734.809
2761.314
2828.224
2830.284
2758.149
2774.943
2782.801
2861.970
2878.688
3049.229
3029.340
3099.041
3071.151
3075.576
3146.372
3005.671
3149.381
There should be seasonality, and I want to estimate this and remove it. I attempted this using the below code:
df <- ts(df$price, frequency = 12, start = c(2016,8))
decompose_df <- decompose( , "additive")
adjust_df<- df- decompose_df $seasonal
plot(adjust_df)
But as I only have 20 months and not two full periods of data, I get the below error:
Error in decompose(df, "additive") :
time series has no or less than 2 periods
Is there a way I can test and remove this seasonality? Even though I only have 20 periods when I need 24.
Use the Kruskal function by using the array and series as parameters. The function returns the p-value. If the p-value is less than 0.05 (5 % significance level) the hypothesis that the series is not seasonal is rejected. Similarly, for Quarterly, arrange the array from 0–2, repeated until the end of the series.
We can use the ACF to determine if seasonality is present in a time series. For example, Yt = γ · St + ϵt. The larger the amplitude of seasonal fluctuations, the more pronounced the oscillations are in the ACF.
Seasonality testseasonal_decompose() tests whether a time series has a seasonality or not by removing the trend and identify the seasonality by calculating the autocorrelation(acf). The output includes the number of period, type of model(additive/multiplicative) and acf of the period.
It's not possible using the usual methods of decomposition because they estimate seasonality using at least as many degrees of freedom as there are seasonal periods. As @useR has pointed out, you need at least two observations per seasonal period to be able to distinguish seasonality from noise.
However, if you are willing to assume that the seasonality is relatively smooth, then you can estimate it using fewer degrees of freedom. For example, you can approximate the seasonal pattern using Fourier terms with a few parameters.
df <- ts(c(
2735.869,2857.105,2725.971,2734.809,2761.314,2828.224,2830.284,2758.149,
2774.943,2782.801,2861.970,2878.688,3049.229,3029.340,3099.041,3071.151,
3075.576,3146.372,3005.671,3149.381), start=c(2016,8), frequency=12)
library(forecast)
library(ggplot2)
decompose_df <- tslm(df ~ trend + fourier(df, 2))
trend <- coef(decompose_df)[1] + coef(decompose_df)['trend']*seq_along(df)
components <- cbind(
data = df,
trend = trend,
season = df - trend - residuals(decompose_df),
remainder = residuals(decompose_df)
)
autoplot(components, facet=TRUE)
You can adjust the order of the Fourier terms as required. I've used 2 here. For monthly data, the maximum you can use is 6, but that will give a model with 13 degrees of freedom which is way too many with only 20 observations. If you don't know about Fourier terms for seasonality, see https://otexts.org/fpp2/useful-predictors.html#fourier-series.
Now we can remove the seasonal component to get the seasonally adjusted data.
adjust_df <- df - components[,'season']
autoplot(df, series="Data") + autolayer(adjust_df, series="Seasonally adjusted")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With