# How can I identify seasonality in this plot

If there is any method/test to check whether the seasonal component is significant in R.

• How to do anything in R is off-topic here without a statistical core, but it would be easy to generalise your question. However, the seasonality tag shows many questions on the topic, so what is new and different here? One short answer is by drawing a plot that is different, as plots of time series extending over several years are poor for identifying seasonality; naturally, more can be said. A minute but not trivial detail with your plot is that although years are intervals your labelled axis ticks are at points and remain ambiguous unless the graph convention is spelled out. – Nick Cox Oct 27 '17 at 11:59
• Plot data versus time of year is a recipe surprisingly often omitted. – Nick Cox Oct 27 '17 at 12:05

Approach 1: Visualisation

Let me summarise an idea from a little book of R for time series.

I use the following time series

births <- scan("https://robjhyndman.com/tsdldata/data/nybirths.dat")
birthstimeseries <- ts(births, frequency = 12, start = c(1946,1))


Now I can decompose the time series

library(TTR)
birthstimeseriescomponents <- decompose(birthstimeseries)


You can either plot all components

plot(birthstimeseriescomponents)


or you just have a look at the seasonal component with

  birthstimeseriescomponents\$seasonal

Jan        Feb        Mar        Apr
1946 -0.6771947 -2.0829607  0.8625232 -0.8016787
1947 -0.6771947 -2.0829607  0.8625232 -0.8016787
1948 -0.6771947 -2.0829607  0.8625232 -0.8016787
1949 -0.6771947 -2.0829607  0.8625232 -0.8016787
1950 -0.6771947 -2.0829607  0.8625232 -0.8016787
1951 -0.6771947 -2.0829607  0.8625232 -0.8016787
1952 -0.6771947 -2.0829607  0.8625232 -0.8016787
1953 -0.6771947 -2.0829607  0.8625232 -0.8016787
1954 -0.6771947 -2.0829607  0.8625232 -0.8016787
1955 -0.6771947 -2.0829607  0.8625232 -0.8016787
1956 -0.6771947 -2.0829607  0.8625232 -0.8016787
1957 -0.6771947 -2.0829607  0.8625232 -0.8016787
1958 -0.6771947 -2.0829607  0.8625232 -0.8016787
1959 -0.6771947 -2.0829607  0.8625232 -0.8016787
May        Jun        Jul        Aug
1946  0.2516514 -0.1532556  1.4560457  1.1645938
1947  0.2516514 -0.1532556  1.4560457  1.1645938
1948  0.2516514 -0.1532556  1.4560457  1.1645938
1949  0.2516514 -0.1532556  1.4560457  1.1645938
1950  0.2516514 -0.1532556  1.4560457  1.1645938
1951  0.2516514 -0.1532556  1.4560457  1.1645938
1952  0.2516514 -0.1532556  1.4560457  1.1645938
1953  0.2516514 -0.1532556  1.4560457  1.1645938
1954  0.2516514 -0.1532556  1.4560457  1.1645938
1955  0.2516514 -0.1532556  1.4560457  1.1645938
1956  0.2516514 -0.1532556  1.4560457  1.1645938
1957  0.2516514 -0.1532556  1.4560457  1.1645938
1958  0.2516514 -0.1532556  1.4560457  1.1645938
1959  0.2516514 -0.1532556  1.4560457  1.1645938
Sep        Oct        Nov        Dec
1946  0.6916162  0.7752444 -1.1097652 -0.3768197
1947  0.6916162  0.7752444 -1.1097652 -0.3768197
1948  0.6916162  0.7752444 -1.1097652 -0.3768197
1949  0.6916162  0.7752444 -1.1097652 -0.3768197
1950  0.6916162  0.7752444 -1.1097652 -0.3768197
1951  0.6916162  0.7752444 -1.1097652 -0.3768197
1952  0.6916162  0.7752444 -1.1097652 -0.3768197
1953  0.6916162  0.7752444 -1.1097652 -0.3768197
1954  0.6916162  0.7752444 -1.1097652 -0.3768197
1955  0.6916162  0.7752444 -1.1097652 -0.3768197
1956  0.6916162  0.7752444 -1.1097652 -0.3768197
1957  0.6916162  0.7752444 -1.1097652 -0.3768197
1958  0.6916162  0.7752444 -1.1097652 -0.3768197

1959  0.6916162  0.7752444 -1.1097652 -0.3768197


If you plot it and you get the raw data of the seasonal component you should be able to make a conclusion.

Approach 2: Statistical testing

The following question seems to be very close to yours and it has some answers: Test for trend and seasonality in time series.

There are also several tests for seasonality such as the Friedman test and the Kruskal-Wallis test. Both test are available in R and apply to stable additive seasonality. The command for the Kruskal-Wallis test is kruskal.test() from the preinstalled stats package. The command for the Friedman test is friedman.test() which is also in the stats package.

Friedman test

The Friedman test is a test which is used to detect differences in treatment across multiple test attempts. It can detect differences in the mean between ≥ 2 samples.

Here is an explanation why the Friedman test is useful for seasonality:

Stable seasonality test (also called an F-test, Friedman test) is a test for the presence of seasonality based on a one-way analysis of variance on the SI ratios. Thus the test is performed on the detrended time series adjusted for prior factors. Generally, the test compares the periods (months or quarters) variance with the residual variance. Under the assumption that the first one is caused by seasonal factors while the second one derives from irregular movements the test checks if the first type of variations are repetitive and regular enough to be reliably identified as the seasonal movements.

Kruskal-Wallis test

The Kruskal-Wallis test is similar to the Friedman test. It also test whether ≥ 2 samples have different means. The Difference to the Friedman test is that the Kruskal-Wallis test is based on an Analysis of Variance (ANOVA) between the samples. For a detailed discussion read this page: Friedman vs Kruskal-Wallis test

Here is an explanation why the Kruskal Wallis Test is useful for detecting seasonality:

Kruskal-Wallis test is a non-parametric test used for comparing samples from two or more groups. This test does not make assumptions about normality. However, it assumes that the observations in each group come from populations with the same shape of distribution. The null hypothesis states that all months (or quarters, respectively) have the same mean.

As NickCox already stated in the comment these test are available in almost every package of statistical software.

• This is helpful for R users but indulges the off-topic flavour of the question. A simple improvement would be to spell out why these tests are relevant to seasonality. That would help other people as such tests are (a) not quite obviously tests of seasonality (e.g. do they respect time-of-year order?) (b) widely available in other software. – Nick Cox Oct 27 '17 at 11:50
• @NickCox I fixed the url and I will extend my answer. – Ferdi Oct 27 '17 at 13:08

https://robjhyndman.com/hyndsight/detecting-seasonality/

...One simple approach is to fit a model with allows for seasonality if it is present. For example, you can fit an ETS model using ets() in R, and if the chosen model has a seasonal component, then the data is seasonal...

...Personally, I never bother with the hypothesis test as I think it answers the wrong question. If the hypothesis test is significant, we can conclude that the data are very unlikely to have been generated from the simpler (non-seasonal) model. But I don’t actually believe the data were generated by any ETS model, so all this is telling me is that I have enough data to be able to see the difference between my data and the model.

A more useful question is to ask if the seasonal component improves forecast accuracy, and that is precisely what the AIC is telling us. ...

• Hi, and thanks for a good first answer! Could you perhaps edit it to contain the gist of the content of Rob's blog post? In that case, the answer will remain even if the link goes dead some day. Thanks again! – Stephan Kolassa Oct 27 '17 at 8:51
• Your link is great, but please stay humble. The comment "next time spend 30 seconds googling" is unnecessary. – Ferdi Oct 27 '17 at 9:56
• you are both right, I shouldn't have been rude; I'll edit so that the answer does not depend on the link. – user2089357 Oct 27 '17 at 11:09

As commented, a very simple idea, but one often neglected, is to plot raw data or detrended data versus time of year. Using the New York births data referred to by @Ferdi in his answer (including the crucial detail that these are monthly data starting in January 1946), this kind of simple graph is a start.

Next steps might include fitting a trend or a more comprehensive model, as elsewhere hinted, so the plot is of some possibly seasonal component. For this example, it is hard to think of a sensible model without knowing whether the data have been adjusted for length of month, which may be documented somewhere.

Fuller discussion of graphs for seasonality is included in this paper and this note. People who don't use Stata will just want to hum and skip through those details, but the ideas and results transcend software choice.

• Great answer. You can also get this kind of plot with the "seasonplot()" function from the "forecast" package in R. – Ferdi Oct 27 '17 at 16:44