18

I have made a simple time-series, i added a little noise to a sin function and tried to decompose it using the "stl" and "decompose" function in R, while my series definitely has more than 2 period and is periodic, R gives me the following error for both functions:

x
  [1]  1.4537365796  2.7185844368  2.8394728999  3.8926989923  4.3405508086  5.1959080871
  [7]  5.6602505790  5.4829985648  5.6357660330  4.6084976233  4.6617322922  4.0286486832
 [13]  3.3641752333  1.7408063182  0.8815147612  0.2895139342 -0.5402768515 -1.5612641107
 [19] -2.1584502547 -2.9878043526 -3.5545638149 -4.0530074199 -4.0748538612 -4.7581704662
 [25] -4.6555349052 -4.0726206240 -3.1646413472 -2.6934453823 -2.2364605277 -1.2643569882
 [31] -0.1202011946  1.1136371449  2.2504199271  3.0313528996  3.5384449109  4.5176211013
 [37]  5.4013172839  5.4252837451  5.4768196692  5.8979709077  5.6698285659  4.5133489450
 [43]  4.2702602998  3.5180837069  2.2652913344  1.1975595698  0.5412697849 -0.5966162032
 [49] -1.0827728340 -1.8488242277 -3.4118061838 -3.9009752140 -3.9102671954 -4.3486102172
 [55] -4.7481017993 -4.0097598695 -3.9078554267 -3.8070416888 -2.5968567322 -2.2567568949
 [61] -1.1423907008  0.0002492447  0.4338279080  1.2431986797  2.3216397323  3.3235925116
 [67]  4.1591487169  4.9028481873  5.4535861470  5.0579349546  5.1548777627  4.9707124992
 [73]  5.4496833187  4.4563072487  4.1301372986  2.4594352788  1.7253019929  0.6961453965
 [79]  0.4281167695 -1.3152944759 -1.8645880957 -2.5764132038 -3.7681528112 -4.3731672862
 [85] -3.9940201611 -4.5497596299 -4.9496796983 -4.1233093447 -3.7759837204 -3.3359027749
 [91] -2.3518009102 -1.7488933797 -0.7225148838  0.5395759836  1.0496249652  2.0383715782
 [97]  3.2357449979  3.8028316517  5.0346866280  5.2154265148

fit<- stl(x, t.window=15, s.window="per", robust=TRUE)
Error in stl(x, t.window = 15, s.window = "per", robust = TRUE) :series is not periodic or has less      than two periods

fit<- decompose(x,type="multiplicative")
Error in decompose(x, type = "multiplicative") :time series has no or less than 2 periods

Would someone help me with this problem please?

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
Etan A Ehsanfar
  • 321
  • 1
  • 3
  • 7

1 Answers1

18

Isn't it obvious from the error message:

time series has no or less than 2 periods

? R's not telling you your data aren't periodic, just that the data you passed it have no indication that they are periodic.

Your time series x doesn't have an periodicity from the point of view of R. It looks like you forgot to tell, or made an error in telling, ts() what the periodicity is. As you don't show how x was created, there isn't much we can do except tell you to go back and create x so that it does have >=2 periods.

The point here is that on it's own, R can't deduce what the frequency of observation is per unit time. You have to tell ts() that information. You can do this in a number of ways:

frequency: the number of observations per unit of time.

deltat: the fraction of the sampling period between successive observations; e.g., 1/12 for monthly data. Only one of frequency or deltat should be provided.

If you don't provide one of these, ts() uses the defaults frequency = 1, deltat = 1 which would indicate a time series of one observation per unit time (one per year for example).

stl() requires a "ts" classed object - if you don't provide one, it will coerce the input data to a "ts" object via as.ts(). This function will use the defaults which I describe above.

What I think has happened here is that you didn't realise that stl() requires a "ts" class object nor that it created an inappropriate one for your data when you just supplied the vector of observations.

The solution would be to explicitly create the "ts" classed object via ts() and specify one of frequency or deltat.

E.g.

dat <- cumsum(rnorm(12*4))
x <- ts(dat)
stl(x, "periodic")
xx <- ts(dat, frequency = 12)
stl(xx, "periodic")

Here I used frequency = 12 to indicate that there are 12 observations per unit time --- such as with monthly data.

The above gives for me

R> stl(x, "periodic")
Error in stl(x, "periodic") : 
  series is not periodic or has less than two periods

R> stl(xx, "periodic")
 Call:
 stl(x = xx, s.window = "periodic")

Components
       seasonal    trend remainder
Jan 1 -0.103529  0.55245  -0.44301
Feb 1  0.001333  0.56981   0.86135
Mar 1 -0.382075  0.58717   1.11162
Apr 1  0.010552  0.59891  -1.04966
....

For your data I suspect you want frequency = 10 given the length of the time series; that would say that you have ten observations per year. If the series has more observations per year, say 12 for monthly data, but you don;t have the last two or first two months (i.e. there is no missing data, NAs) you just started (ended) later (earlier) in the year and hence don't have a full years worth of data at one or both ends of the series.

Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • 2
    sorry if it was obvious, I am new in R, however, my assumption was a periodic series are regular series which contain certain frequencies in their Fourier Transform, mine had this because I created it using Sin function – Etan A Ehsanfar Jan 14 '14 at 21:00
  • 2
    Yes, but as far as the computer knows or cares, it is just a vector of numbers with no indication as the time points at which these were observed. – Gavin Simpson Jan 14 '14 at 21:11
  • 1
    Good and detailed answer, but I get this error message when trying to analyze hourly data (`xxx <- ts(x, freq=24)`). Is there, perhaps, a limit on time series length or on the number of observations per cycle? Edit: I have missing values, and I've tried using both `na.action=na.pass` and `na.action=na.exclude`. – rbatt Sep 26 '17 at 18:39
  • @rbatt I can't reproduce your problem (`stl(ts(rnorm(1000), frequency = 24), "periodic")`) so some other detail matters, but looking at the code we see `if (period < 2 || n <= 2 * period)` so unless you have more than 2 "periods" in the data you'll get that error message. Does that match with your data? – Gavin Simpson Sep 26 '17 at 18:53
  • 1
    @rbatt That check comes *after* the `NA`s have been removed, so it is likely that you do have more observations than 2 * 24 until the `NA`s get removed and once they're removed your data doesn't make the length threshold. It appears that the `na.action` argument doesn't actually do anything. – Gavin Simpson Sep 26 '17 at 19:00
  • @GavinSimpson I have about 119 periods. I just tried subsetting to the first 6 periods --- none of these values were NA, and it worked fine. I then linearly interpolated the full time series, and that also worked. Seems that `stl` does not work with `NA` values! Thanks for your thoughts. – rbatt Sep 26 '17 at 20:13
  • @rbatt It appears that is so; I understood you were getting the same error message, but the only way I can recreate an error is to add `NA`s and then I see a different error: `Error in na.fail.default(as.ts(x)) : missing values in object`. Looking at the code it is clear that currently it can't do anything with `NA`s and will always fail, no matter what you pass the na.action argument. You might try fitting using a GAM via the **mgcv** package. – Gavin Simpson Sep 26 '17 at 20:30
  • did you do `stl(..., na.action=na.exclude)` or `na.pass`? I got a similar error message to you before specifying that argument. I haven't looked at the function's code, so it's weird if that would make a difference if it doesn't looked like `na.action` does anything. – rbatt Sep 28 '17 at 13:46