How to statistically compare two time series?

I have two time series, shown in the plot below:

The plot is showing the full detail of both time series, but I can easily reduce it to just the coincident observations if needed.

My question is: What statistical methods can I use to assess the differences between the time series?

I know this is a fairly broad and vague question, but I can't seem to find much introductory material on this anywhere. As I can see it, there are two distinct things to assess:

1. Are the values the same?

2. Are the trends the same?

What sort of statistical tests would you suggest looking at to assess these questions? For question 1 I can obviously assess the means of the different datasets and look for significant differences in distributions, but is there a way of doing this that takes into account the time-series nature of the data?

For question 2 - is there something like the Mann-Kendall tests that looks for the similarity between two trends? I could do the Mann-Kendall test for both datasets and compare, but I don't know if that is a valid way to do things, or whether there is a better way?

I'm doing all of this in R, so if tests you suggest have a R package then please let me know.

• The plot appears to obscure what may be a crucial difference between these series: they might be sampled at different frequencies. The black line (Aeronet) seems to be sampled only about 20 times and the red line (Visibility) hundreds of times or more. Another critical factor may be the regularity of sampling, or lack thereof: the times between Aeronet observations appear to vary a little. In general, it helps to erase the connecting lines and display only the points corresponding to actual data, so that the viewer can determine these things visually.
– whuber
Commented Nov 29, 2011 at 18:11
• Here is a Python library for unevenly-spaced time series analysis. Commented Nov 4, 2018 at 13:12
• Drop a link to a lecture notes that discussed this problem for future readers
– Tung
Commented Sep 1, 2021 at 5:40
• Not a great fan of Mann-Kendall. You could fit a GAM to each series and at least compare the confidence envelopes. There's probably a way to statistically compare the two fits formally too. Commented Sep 12, 2021 at 19:26

As others have stated, you need to have a common frequency of measurement (i.e. the time between observations). With that in place I would identify a common model that would reasonably describe each series separately. This might be an ARIMA model or a multiply-trended Regression Model with possible Level Shifts or a composite model integrating both memory (ARIMA) and dummy variables. This common model could be estimated globally and separately for each of the two series and then one could construct an F test to test the hypothesis of a common set of parameters.

• Well, you don't really need to have the same frequency for both series. It just that so fare there is little software for other cases, but see traces.readthedocs.io/en/latest. It seems like much is pubslihed about other cases in astronomy journals and in finance and geophysics ... see refs in en.wikipedia.org/wiki/Unevenly_spaced_time_series Commented Nov 4, 2018 at 18:05

Consider the grangertest() in the lmtest library.

It is a test to see if one time series is useful in forecasting another.

A couple references to get you started:

https://spia.uga.edu/faculty_pages/monogan/teaching/ts/

https://spia.uga.edu/faculty_pages/monogan/teaching/ts/Kgranger.pdf

http://en.wikipedia.org/wiki/Granger_causality

• His sample size would be too small with < 10 datapoints versus the amount of parameters you need to fit in Granger.
– Jase
Commented Dec 27, 2012 at 6:07

Just came across this. Your first answer us plotting g the two sets the same scale (timewise) to see the differences visually. You have done this and can easily see there are some glaring differences. The next step is to use simple correlation analysis...and see how well are they related using the correlation coefficient (r). If the r is small your conclusion would be that they are weakly related and so no desirable comparisons and a larger value if r would suggest good comparisons s between the two series. The third step where there is good correlation is to test the statistical significance of the r. Here you can use the Shapiro Welch test which would assume the two series are normally distributed (null hypothesis ) or not (alternative hypothesis). There are other tests you can do but let me hope my answer helps.

• When comparing time series it is autocorrelation and possibly fitting time series models. such as ARIMA models that can help determine how similar they are. Two realizations of the same stochastic process don't necessarily look the same when plotting them. Commented Feb 9, 2019 at 2:28
• @MichaelR.Chernick But often when comparing time series you are more interested in the particular realisations than the statistical properties. Commented Sep 2, 2021 at 1:09

I want to propose another approach. This is to test whether two time series are the same. This approach is only suitable for infrequently sampled data where autocorrelation is low.

If time series x is the similar to time series y then the variance of x-y should be less than the variance of x. We can test this using a one sided F test for variance. If the ratio var(x-y)/var(x) is significantly less than one then then y explains a significant proportion of the variance of x.

We also need to check that x-y is not significantly different to 0. This can be done with a one sample two sided t.test.

x <- cumsum(runif(10)-0.5)
t <- seq_along(x)
y <- x + rnorm(10, 0, 0.2)
# y <- x + rnorm(10, 0.2, 0.2)
plot(t,x, "b", col = "red")
points(t,y, "b", col = "blue")


var.test(x-y, x, alternative = "less") # does y improve variance of x?
#>
#>  F test to compare two variances
#>
#> data:  x - y and x
#> F = 0.27768, num df = 9, denom df = 9, p-value = 0.03496
#> alternative hypothesis: true ratio of variances is less than 1
#> 95 percent confidence interval:
#>  0.0000000 0.8827118
#> sample estimates:
#> ratio of variances
#>           0.277679
t.test(x-y) # check that x-y does not have an offset
#>
#>  One Sample t-test
#>
#> data:  x - y
#> t = -0.0098369, df = 9, p-value = 0.9924
#> alternative hypothesis: true mean is not equal to 0
#> 95 percent confidence interval:
#>  -0.1660619  0.1646239
#> sample estimates:
#>     mean of x
#> -0.0007189834


Created on 2021-09-02 by the reprex package (v2.0.0)

I think it should be possible to extend this approach to test whether two time series are linearly correlated, using x-lm(x ~ y) instead of x-y.

Edit: Dealing with autocorrelation I think could be done by finding a suitable Effective Degrees of Freedom for the tests, c.f., https://doi.org/10.1016/j.neuroimage.2019.05.011

Fit a straight line to both the time series signals using polyfit. Then compute root-mean-square-error (RMSE) for both the lines. The obtained value for the red-line would be quite less than the one obtained for gray line.

Also make the readings on some common frequency.

• Welcome to Cross Validated and thanks for your first answer! I am however concerned that you are not answering the question directly - how exactly would the proposed approach help the asker to asses whether the values and/or trends are similar? Commented Mar 12, 2018 at 9:49

For question 1, I believe a cluster permutation test would suit you best.

I propose the following: At the time stamps, get mean of the two series. Subtract the mean from the two time series. Take histogram of the subtracted values, use significance test. My case is the following:

This I flattened across the mean values of the two groups

grouped_df['Mean_Neg_Pos'] = (grouped_df['Negative'] +
grouped_df['Positive'])/2
plt.clf()
plt.figure(figsize=(10, 6))
plt.hist(grouped_df['Negative']-grouped_df['Mean_Neg_Pos'],
label='Negative', color='r', alpha=0.5)
plt.hist(grouped_df['Positive']-grouped_df['Mean_Neg_Pos'],
label='Positive', color='b', alpha=0.5)
plt.show()


This gives me the following result:

Comparing means gives statistical difference between two time series:

# Calculate the difference between Negative and Mean_Neg_Pos
group1 = grouped_df['Negative'] - grouped_df['Mean_Neg_Pos']

# Calculate the difference between Positive and Mean_Neg_Pos
group2 = grouped_df['Positive'] - grouped_df['Mean_Neg_Pos']

# Perform the significance test
t_stat, p_value, _ = ttest_ind(group1, group2)

t_stat, p_value # (-13.322573312844817, 3.1347222952928475e-35)