Skip to contents

spp_test() provides a simulation approach to assessing unit root in a time series by way of the Phillips-Perron test. It takes a vector and performs three Phillips-Perron tests (no drift, no trend; drift, no trend; drift and trend) and calculates both rho and tau statistics as one normally would. Rather than interpolate or approximate a p-value, it simulates some user-specified number of Phillips-Perron tests of either a known, non-stationary time series or a known, white-noise time series matching the length of the time series the user provides. This allows the user to make assessments of non-stationarity or stationarity by way of simulation rather than approximation from received critical values by way of various books/tables.

Usage

spp_test(x, lag_short = TRUE, n_sims = 1000, sim_hyp = "nonstationary")

Arguments

x

a vector

lag_short

logical, defaults to TRUE. If TRUE, the "short-term" lag is used for the Phillips-Perron test. If FALSE, the "long-term" lag is used.

n_sims

the number of simulations for calculating an interval or distribution of test statistics for assessing stationarity or non-stationarity. Defaults to 1,000.

sim_hyp

can be either "stationary" or "nonstationary". If "stationary", the function runs Phillips-Perron tests on simulated stationary (pure white noise) data. This allows the user to assess compatibility/plausibility of the test statistic against a distribution of test statistics that are known to be pure white noise (in expectation). If "nonstationary" (default), the function generates three different data sets of a pure random walk, a random walk with a drift, and a random walk with a drift and trend. It then runs Phillips-Perron tests on all those. This allows the user to assess the compatibility/plausibility of their test statistics with data that are known to be nonstationary in some form.

Value

spp_test() returns a list of length 3. The first element in the list is a matrix of rho statistics and tau statistics calculated by the Phillips-Perron test. The second element is a data frame of the simulated rho and tau statistics of either a known white-noise time series or three different non-stationary time series (pure random walk, random walk with drift, random walk with drift and trend). The third element is some attributes about the procedure for post-processing.

Details

Some knowledge of Augmented Dickey-Fuller and the Phillips-Perron procedure is assumed here. Generally, the Phillips-Perron test purports to build on the Augmented Dickey-Fuller procedure through two primary means. The first is relaxing the need to specify or assume lag structures ad hoc or ex ante. Only a short-term lag or long-term lag are necessary. The second is that its robust to various forms of heteroskedasticity in the error term.

The short-term and long-term lags follow the convention introduced in the Phillips-Perron test. The short-term lag uses the default number of Newey-West lags, defined as the floor of 4*(n/100)^.25 where n is the length of the time series. The long-term lag substitutes 4 for 12 in this equation. We have Schwert (1989) to thank for these defaults.

This function specifies three different types of tests: 1) no drift, no trend, 2) drift, no trend, and 3) drift and trend. In the language of the lm() function, the first is lm(y ~ ly - 1) where y is the value of y and ly is its first-order lag. The second test is lm(y ~ ly), intuitively suggesting the y-intercept in this equation is the "drift". The third would be lm(y ~ ly + t) with t being a simple integer that increases by 1 for each observation (i.e. a time-trend).

There are two types of statistics in the Phillips-Perron test: rho and tau. Of the two, tau is the more intuitive statistic and compares favorably to its corollary statistic in the Augmented Dickey-Fuller test. It's why you'll typically see tau reported as the statistic of interest in other implementations. rho has its utility for more advanced diagnostics, though. Both are calculated in this function, though tau is the default statistic.

None of this is meant to discourage the use of Fuller (1976) or its various reproductions for the sake of diagnosing stationarity or non-stationary, and I will confess their expertise on these matters outpaces mine. Consider the justification for this function to be largely philosophical and/or experimental. Why not simulate it? It's not like time or computing power are huge issues anymore.

This is always awkwardly stated, but it's a good reminder that the classic Dickey-Fuller statistics are mostly intended to come back negative. That's not always the case, to be clear, but it is the intended case. You assess the statistic by "how negative" it is. Stationary time series will produce test statistics more negative ("smaller") than those produced by non-stationary time series. In a way, this makes the hypotheses implicitly one-tailed (to use that language).

This function removes missing values from the vector before calculating test statistics.

Author

Steven V. Miller

Examples


a <- rnorm(25) # white noise
b <- cumsum(a) # random walk

spp_test(a, n_sims = 25)
#> $stats
#>           [,1]      [,2]
#> [1,] -23.48328 -4.605517
#> [2,] -23.93430 -4.742632
#> [3,] -24.00217 -4.645973
#> 
#> $sims
#>          z_rho      z_tau sim                cat
#> 1    1.1294248  0.6367477   1 No Drift, No Trend
#> 2   -0.9068868 -0.3079832   1    Drift, No Trend
#> 3   -2.8966041 -1.1404323   1    Drift and Trend
#> 4   -0.7370774 -0.5985780   2 No Drift, No Trend
#> 5   -4.3622620 -1.4757252   2    Drift, No Trend
#> 6  -13.1058554 -2.7077509   2    Drift and Trend
#> 7  -10.8416351 -2.5858515   3 No Drift, No Trend
#> 8  -11.9029908 -2.6907983   3    Drift, No Trend
#> 9  -14.9289381 -2.2962002   3    Drift and Trend
#> 10 -13.4938711 -2.9331418   4 No Drift, No Trend
#> 11 -13.5393488 -2.8677585   4    Drift, No Trend
#> 12  -7.0149008 -1.6514995   4    Drift and Trend
#> 13  -1.6569621 -0.7541765   5 No Drift, No Trend
#> 14  -1.3397403 -0.4127787   5    Drift, No Trend
#> 15  -9.1850058 -2.1199585   5    Drift and Trend
#> 16  -0.2128096 -0.1053604   6 No Drift, No Trend
#> 17  -1.6067642 -0.7113448   6    Drift, No Trend
#> 18 -14.3960703 -2.9488911   6    Drift and Trend
#> 19  -0.8852778 -0.4728312   7 No Drift, No Trend
#> 20 -10.2493271 -2.4628553   7    Drift, No Trend
#> 21  -6.6265427 -2.4029418   7    Drift and Trend
#> 22  -2.2075688 -1.0235998   8 No Drift, No Trend
#> 23  -4.5009687 -1.6618158   8    Drift, No Trend
#> 24 -11.2699230 -2.6610279   8    Drift and Trend
#> 25  -1.7287100 -0.7520601   9 No Drift, No Trend
#> 26  -3.9257714 -1.3600884   9    Drift, No Trend
#> 27  -9.1225129 -2.1384250   9    Drift and Trend
#> 28  -1.7120964 -0.9058208  10 No Drift, No Trend
#> 29  -3.9958306 -1.8616200  10    Drift, No Trend
#> 30 -14.1509870 -2.7001421  10    Drift and Trend
#> 31   0.3350596  0.3517101  11 No Drift, No Trend
#> 32  -8.3573022 -4.1165346  11    Drift, No Trend
#> 33  -7.1841876 -1.8738945  11    Drift and Trend
#> 34  -0.9725538 -0.6543340  12 No Drift, No Trend
#> 35  -3.3052661 -1.5300153  12    Drift, No Trend
#> 36  -9.5129526 -2.0997490  12    Drift and Trend
#> 37  -2.4244423 -0.8173012  13 No Drift, No Trend
#> 38  -1.4792524 -0.4398537  13    Drift, No Trend
#> 39 -10.5034794 -3.0627737  13    Drift and Trend
#> 40   1.0489293  1.0831857  14 No Drift, No Trend
#> 41  -0.5863368 -0.4401832  14    Drift, No Trend
#> 42  -1.4004534 -0.4861305  14    Drift and Trend
#> 43  -5.5971047 -1.6821989  15 No Drift, No Trend
#> 44  -5.3897665 -1.6632667  15    Drift, No Trend
#> 45  -9.9472249 -2.3416121  15    Drift and Trend
#> 46  -2.3468982 -0.6816219  16 No Drift, No Trend
#> 47  -3.4135118 -0.9665459  16    Drift, No Trend
#> 48 -10.1314544 -2.8415270  16    Drift and Trend
#> 49   0.3331753  0.2755908  17 No Drift, No Trend
#> 50  -7.0605106 -2.0357348  17    Drift, No Trend
#> 51 -10.9990568 -2.1880948  17    Drift and Trend
#> 52  -4.1434352 -1.4798280  18 No Drift, No Trend
#> 53  -4.7661190 -1.5652520  18    Drift, No Trend
#> 54 -14.5727902 -3.2601228  18    Drift and Trend
#> 55  -0.6899220 -0.2818260  19 No Drift, No Trend
#> 56  -5.1785999 -1.3979981  19    Drift, No Trend
#> 57 -11.1952575 -2.4972148  19    Drift and Trend
#> 58  -4.0861377 -1.4702544  20 No Drift, No Trend
#> 59  -9.0703605 -2.9483743  20    Drift, No Trend
#> 60  -5.5077254 -1.5515693  20    Drift and Trend
#> 61   1.1451524  1.4419096  21 No Drift, No Trend
#> 62  -1.5161716 -1.0733236  21    Drift, No Trend
#> 63  -9.4416130 -2.0419656  21    Drift and Trend
#> 64  -1.3146850 -0.8281979  22 No Drift, No Trend
#> 65  -5.3907277 -1.4219443  22    Drift, No Trend
#> 66  -3.6900973 -1.3826374  22    Drift and Trend
#> 67  -1.6277517 -0.7807940  23 No Drift, No Trend
#> 68  -0.5909836 -0.1782738  23    Drift, No Trend
#> 69  -3.7388786 -0.9820553  23    Drift and Trend
#> 70  -5.3306989 -1.5107292  24 No Drift, No Trend
#> 71  -7.4218936 -1.4706567  24    Drift, No Trend
#> 72  -1.0078166 -0.4979061  24    Drift and Trend
#> 73   0.9115373  0.8317744  25 No Drift, No Trend
#> 74  -4.5454840 -1.8091737  25    Drift, No Trend
#> 75 -10.3592143 -2.8115282  25    Drift and Trend
#> 
#> $attributes
#>   lags       sim_hyp n_sims  n test
#> 1    2 nonstationary     25 25   pp
#> 
#> attr(,"class")
#> [1] "spp_test"
spp_test(b, n_sims = 25)
#> $stats
#>            [,1]       [,2]
#> [1,]  0.3242636  0.2688907
#> [2,] -4.7454538 -1.8513845
#> [3,] -9.1278106 -2.3117382
#> 
#> $sims
#>            z_rho        z_tau sim                cat
#> 1  -1.665619e-01 -0.146684873   1 No Drift, No Trend
#> 2  -3.673281e+00 -1.801378886   1    Drift, No Trend
#> 3  -3.628388e+00 -0.968229690   1    Drift and Trend
#> 4  -8.205472e+00 -2.070028595   2 No Drift, No Trend
#> 5  -8.356446e+00 -1.963371279   2    Drift, No Trend
#> 6  -1.003390e+01 -2.226467957   2    Drift and Trend
#> 7  -2.851732e+00 -1.149330596   3 No Drift, No Trend
#> 8  -2.505238e+00 -1.046419455   3    Drift, No Trend
#> 9  -1.321583e+01 -2.762012427   3    Drift and Trend
#> 10 -7.132989e+00 -1.995266950   4 No Drift, No Trend
#> 11 -8.032439e+00 -2.007359026   4    Drift, No Trend
#> 12 -8.263651e+00 -1.907754237   4    Drift and Trend
#> 13 -3.475496e-02 -0.035872616   5 No Drift, No Trend
#> 14 -2.922238e+00 -1.715247990   5    Drift, No Trend
#> 15 -1.038536e+01 -2.192730337   5    Drift and Trend
#> 16  2.333278e+00  1.487522698   6 No Drift, No Trend
#> 17  4.985550e-01  0.224519350   6    Drift, No Trend
#> 18 -5.879713e+00 -1.974101549   6    Drift and Trend
#> 19  1.130417e+00  0.686076168   7 No Drift, No Trend
#> 20 -2.847960e+00 -0.878231831   7    Drift, No Trend
#> 21 -7.903666e+00 -1.770855762   7    Drift and Trend
#> 22 -8.617611e-01 -0.518689155   8 No Drift, No Trend
#> 23 -5.741963e+00 -1.913131888   8    Drift, No Trend
#> 24 -1.697466e+01 -3.930401854   8    Drift and Trend
#> 25 -3.634477e+00 -1.353857074   9 No Drift, No Trend
#> 26 -5.972684e+00 -1.754341983   9    Drift, No Trend
#> 27 -6.218477e+00 -1.712368319   9    Drift and Trend
#> 28 -3.911904e+00 -1.341573914  10 No Drift, No Trend
#> 29 -4.124724e+00 -1.281217200  10    Drift, No Trend
#> 30 -1.085643e+01 -2.247249365  10    Drift and Trend
#> 31  1.014780e+00  1.707974563  11 No Drift, No Trend
#> 32 -1.263663e+00 -0.854009961  11    Drift, No Trend
#> 33 -1.164529e+00 -0.224714447  11    Drift and Trend
#> 34 -1.561863e+00 -0.807364973  12 No Drift, No Trend
#> 35 -3.000557e+00 -1.311735953  12    Drift, No Trend
#> 36 -1.680064e+01 -3.354111709  12    Drift and Trend
#> 37  1.667810e+00  1.639584873  13 No Drift, No Trend
#> 38 -3.047593e-01 -0.194022367  13    Drift, No Trend
#> 39 -1.587200e+00 -0.670641555  13    Drift and Trend
#> 40  4.024234e-02  0.030915219  14 No Drift, No Trend
#> 41 -1.613374e+00 -1.036147183  14    Drift, No Trend
#> 42 -1.847518e+01 -3.740452738  14    Drift and Trend
#> 43  3.330698e-01  0.275905325  15 No Drift, No Trend
#> 44 -2.439247e+00 -1.197556256  15    Drift, No Trend
#> 45 -1.247711e+01 -2.515982393  15    Drift and Trend
#> 46  1.009456e+00  0.704712093  16 No Drift, No Trend
#> 47 -2.960559e+00 -0.926808108  16    Drift, No Trend
#> 48 -4.600844e+00 -1.407315036  16    Drift and Trend
#> 49  5.731102e-02  0.051154589  17 No Drift, No Trend
#> 50 -2.884286e+00 -1.470308083  17    Drift, No Trend
#> 51 -1.010458e+01 -2.356348984  17    Drift and Trend
#> 52  1.480332e+00  1.850215004  18 No Drift, No Trend
#> 53 -6.276449e-04  0.006203227  18    Drift, No Trend
#> 54 -5.099533e+00 -1.409227882  18    Drift and Trend
#> 55 -6.306361e-01 -0.323474973  19 No Drift, No Trend
#> 56 -3.820332e+00 -1.313354679  19    Drift, No Trend
#> 57 -5.704391e+00 -1.905547132  19    Drift and Trend
#> 58  1.598719e-01  0.183638205  20 No Drift, No Trend
#> 59 -1.240748e+01 -4.370252774  20    Drift, No Trend
#> 60 -6.028731e+00 -2.103354734  20    Drift and Trend
#> 61  5.273312e-02  0.037127424  21 No Drift, No Trend
#> 62 -2.160675e+00 -1.255057063  21    Drift, No Trend
#> 63 -3.296475e+00 -1.225400068  21    Drift and Trend
#> 64  1.854018e+00  1.505443416  22 No Drift, No Trend
#> 65  5.742201e-01  0.463514798  22    Drift, No Trend
#> 66 -1.343317e+01 -2.754901321  22    Drift and Trend
#> 67 -9.768731e-01 -0.518062974  23 No Drift, No Trend
#> 68 -1.119991e+01 -2.726869427  23    Drift, No Trend
#> 69 -9.227291e+00 -2.093362415  23    Drift and Trend
#> 70 -6.078577e-01 -0.240509603  24 No Drift, No Trend
#> 71 -1.934166e+00 -0.674362003  24    Drift, No Trend
#> 72 -1.088283e+01 -2.847411988  24    Drift and Trend
#> 73  2.223602e+00  2.957131020  25 No Drift, No Trend
#> 74  1.137741e+00  0.867337028  25    Drift, No Trend
#> 75 -1.566082e+01 -3.088469755  25    Drift and Trend
#> 
#> $attributes
#>   lags       sim_hyp n_sims  n test
#> 1    2 nonstationary     25 25   pp
#> 
#> attr(,"class")
#> [1] "spp_test"