# Is there some way to implement automatic TimeSeries extrapolation or series continuation?

I am working with a large number of TimeSeries of irregular length. This means that if I sum them, or compute the mean, it cuts off at the terminus of the shortest series. Is there a convenient way to make it compute to the end of the longest series, assuming that the missing data did not change?

For example, given

test1 = TimeSeries[{{{2000, 1, 1}, 1}, {{2001, 1, 1}, 2}, {{2002, 1, 1}, 3}}];
test2 = TimeSeries[{{{2000, 1, 1}, 2}, {{2001, 1, 1}, 2}}];


Mathematica computes Mean[{test1, test2}]["Values"] to be {1.5, 2}. I would prefer to get {1.5, 2, 2.5}.

What is a straightforward way to do this?

• Extrapolating the data in your 2nd example as flat seems reasonable for that toy example, but what reason do you have for believing that will always be a good way to go? Commented Jan 5, 2016 at 16:55
• Mean[{ArrayPad[test2["Values"], {0, 1}, "Fixed"], test1["Values"]}]? Commented Jan 5, 2016 at 16:57
• @m_goldberg For my data, it's better than omitting these dates entirely. Commented Jan 5, 2016 at 16:57
• Try TimeSeriesThread[Mean, {test1, test2}]["Values"]. You can play around with the ResamplingMethod for each time series to have more control over the result. Commented Jan 5, 2016 at 17:11
• @AndyRoss the docs only reveal "Interpolation" as a possible method so while you could play around with the interpolation order (and are there any other additional options available for the interpolation resampling method ..the docs imply there are) what other methods are available? Commented Jan 5, 2016 at 23:18

The simple answer to this is to use TimeSeriesThread which will perform the extrapolation you are after (though it will rightly complain about extrapolating).

test1 = TimeSeries[{{{2000, 1, 1}, 1}, {{2001, 1, 1}, 2}, {{2002, 1, 1}, 3}}];
test2 = TimeSeries[{{{2000, 1, 1}, 2}, {{2001, 1, 1}, 2}}];

(* {3/2, 2, 5/2} *)


If you want finer control over the extrapolation you can set the ResamplingMethod on each TimeSeries object. The documentation is pretty thin on options. Currently the only documented possibilities are to either use a constant or to set interpolation options. By default, linear interpolation is used for TimeSeries.

In your case, using a constant makes sense and doesn't complain about extrapolation.

test1 = TimeSeries[{{{2000, 1, 1}, 1}, {{2001, 1, 1}, 2}, {{2002, 1, 1}, 3}},
ResamplingMethod -> {"Constant", 3}];

test2 = TimeSeries[{{{2000, 1, 1}, 2}, {{2001, 1, 1}, 2}},
ResamplingMethod -> {"Constant", 2}];

(* {3/2, 2, 5/2} *)


You can also set various interpolation options. In fact, you can use any valid option setting for Interpolation. For example, say you wanted to do zero order interpolation.

m = {"Interpolation", InterpolationOrder -> 0};

test1 = TimeSeries[{{{2000, 1, 1}, 1}, {{2001, 1, 1}, 2}, {{2002, 1, 1}, 3}},
ResamplingMethod -> m];

test2 = TimeSeries[{{{2000, 1, 1}, 2}, {{2001, 1, 1}, 2}},
ResamplingMethod -> m];

(* {3/2, 2, 5/2} *)


Finally, you can create your own resampling method. The usual warnings apply here since this is undocumented functionality and is subject to change.

ResamplingMethod can be given as a function that takes the TemporalData object (TimeSeries is a special case) and returns a list of Listable functions, one for each path, that return a value given a time or list of times. These are what is returned by the "PathFunctions" property of TemporalData.

Suppose we want to do linear interpolation for values in the range of the TimeSeries and then give the last value for all times beyond the TimeSeries. We can create a function that does this as such.

f[ts_TemporalData] := Block[{fns, mxs, vs},
fns = Interpolation[#, InterpolationOrder -> 1] & /@ ts["Paths"];
mxs = Max /@ ts["ValueList"];
vs = Last /@ ts["ValueList"];
Function[\[FormalX],
Piecewise[{{#1[\[FormalX]], \[FormalX] <= #2}}, #3],
Listable] &, {fns, mxs, vs}]
]


Now we can use this function for the ResamplingMethod.

test1 = TimeSeries[{{{2000, 1, 1}, 1}, {{2001, 1, 1}, 2}, {{2002, 1, 1},3}},
ResamplingMethod -> f];

test2 = TimeSeries[{{{2000, 1, 1}, 2}, {{2001, 1, 1}, 2}},
ResamplingMethod -> f];