CSSS/POLS 512: Lab 5

Non-Stationary Time Series

Tao Lin

April 29, 2022

Agenda

  • Review: Counterfactual Forecasting
  • Unit Root Test
  • Differencing
  • Cointegration

Note that we don’t have exercise today. We will finish the part about counterfactual forecasting from last week’s exercise.

For Problem Set 2, the most important techniques are unit root test, model estimation, model selection, and counterfactual forecasting.

Although this Thursday Chris talked a little bit about panel data, I don’t want to go too far ahead. So I will move the panel data part to the next week.

I will return Problem Set 1 next Monday. Two thoughts here:

  • If we are not sure whether it is AR or MA process or how many order it should be, we can look at its longer-term behavior in ACF and PACF plots by specifying, for example, acf(ts, 100).
  • Besides decompose plot and PACF plot, we also need to overplot time series from each cycle to look at repetitive pattern.

Unit Root Test

Unit-root tests are the first step to study and analyze non-stationary time series.

Intuition: if time series is stationary, then regressing \(y_{t}-y_{t-1}\) on \(y_{t-1}\) should produce a negative coefficient. Why?

In a stationary series, knowing the past value of the series helps to predict the next period’s change. Positive shifts should be followed by negative shifts (mean reversion).

\[y_t = \rho y_{t-1} + \epsilon_{t}\] \[y_t - y_{t-1}= \rho y_{t-1} - y_{t-1} + \epsilon_{t}\] \[\Delta y_{t} = \gamma y_{t-1} + \epsilon_{t}\text{, where } \gamma=(\rho - 1)\]

Augmented Dickey-Fuller test: null hypothesis of unit root.

Same with Phillips-Perron test, but differs in how the AR(\(p\)) time series is modeled w.r.t. lags, serial correlation, heteroskedasticity.

ADF Test

The ADF test regression can be expressed as follows:

\[\Delta y_t = \boldsymbol{\beta D_t} + \pi y_{t-1} + \sum^p_{j=1}\psi_j\Delta y_{t-j}+\epsilon_t\] where \(\boldsymbol{D}_t\) is a vector of deterministic trends. The \(p\) lagged difference terms, \(\Delta y_{t-j}\), are used to approximate the ARMA structure of the errors (consider the equivalence of AR and MA models), and the value of \(p\) is set so that the error is serially uncorrelated. The error term is assumed to be homoskedastic.

Under the null hypothesis (\(\rho - 1 = 0\) => unit root => non-stationary), \(\pi\) is set to 0 and is used to construct the ADF test statistic. If we don’t get a statistically significant result from ADF test, then the time series is likely to be stationary.

PP Test

The PP test regression can be expressed as follows:

\[\Delta y_t = \boldsymbol{\beta D_t} + \pi y_{t-1} +u_t\]

The PP test ignores any serial correlation in the test regression. Instead, it corrects for serial correlation and heteroskedasticity in the errors \(u_t\) by directly modifying the test statistic, \(t_{\pi=0}\)

As we can see, both ADF test and PP test assume data has I(\(1\)) non-stationarity. But they also differ in how the time series is modeled. PP test allows for the residuals to be serially correlated.

Sometimes we may find that the results of ADF test and PP test are different. This is because some underlying temporal dependence is not incorporated into the assumed models, or because our sample is too small. For example, if there is a structural break (i.e. persistent arises due to large and infrequent shocks) in the time series, then ADF test tends to gives a non-stationary result.

If we suspect that our time series have particular forms of temporal dependence, we can use the following statistical tests: - higher-order differencing non-stationarity: Kwiatkowski-Phillips-Schmidt-Shin (KPSS) test - Structural break: Zivot-Andrews test, etc.

What is Non-stationary?

Recall that stationary time series have three properties:

  1. Mean stationarity
    • mean does not depend on \(t\), constant over time
    • variance also does not depend on \(t\), constant over time
  2. Covariance stationarity
    • covariance of \(y_t\) and \(y_{t-1}\) do not depend on \(t\)
    • does not depend on the actual time the covariance is computed
  3. Ergodicity
    • sample moments coverge in probability to the population moments
    • sample mean and variance tend to be the same as entire series

Nonstationary procesess lack these properties. Note that we are abstracting from trends and other covariates.

What is Non-stationary?

Why do nonstationary processes matter?

  1. ACF and PACF not defined since the covariances in the nominator depend on \(t\)

  2. Spurious regression: we may detect strong correlations between nonstationary processes although they are really independent

  3. Long run forecasts are very difficult since they do not tend toward any mean

What is Non-stationary?

Solutions?

  1. Analyze nonstationary process using ARIMA (differencing)
    • effective at capturing short run changes
    • outcome is transformed to a difference
    • long-run predictions not feasible
  2. Analyze nonstationary process using cointegration
    • effective at capturing long run relationships between nonstationary processes
    • outcome is left as a level
    • short-run and long-run predictions feasible
    • appropriate for analyzing multiple time series

Studying the Time Series

#Load packages
library(tseries)           # For unit root tests
library(forecast)              # For decompose()
library(lmtest)            # For Breusch-Godfrey LM test of serial correlation
library(urca)              # For estimating cointegration models
library(simcf)             # For counterfactual simulation via ldvsimev()
library(MASS)              # For mvrnorm()
library(RColorBrewer)      # For nice colors
library(Zelig)             # For approval data
library(quantmod)          # For creating lags
source("Lab5_data/TSplotHelper.R")   # Helper function for counterfactual time series plots

###########################################################################
#Load data
#US Presidential approval data (Bush, Monthly, 2/2001--6/2006)
#Includes average oil price data ($/barrel?)
data(approval)
attach(approval)
colnames(approval)
[1] "month"         "year"          "approve"       "disapprove"   
[5] "unsure"        "sept.oct.2001" "iraq.war"      "avg.price"    
# plot presidential approval
plot(approve,type="l",ylab="Percent Approving",xlab="Time",
     main = "US Presidential Approval")
lines(x=c(8,8),y=c(-1000,1000),col="red")
lines(x=c(26,26),y=c(-1000,1000),col="blue")
text("9/11",x = 10, y = 40, col="red",cex=0.7)
text("Iraq \n War",x = 28, y = 40, col="blue",cex=0.7) 

# plot average oil price
plot(avg.price,type="l",ylab="$ per Barrel",xlab="Time",
     main = "Average Price of Oil")
lines(x=c(8,8),y=c(-1000,1000),col="red")
lines(x=c(26,26),y=c(-1000,1000),col="blue")
text("9/11",x = 10, y = 175, col="red",cex=0.7)
text("Iraq \n War",x = 28, y = 175, col="blue",cex=0.7) 

Unit Root Tests

Conflicting results from PP and ADF tests may suggest a structural break within the time series of presidential approval.

PP.test(approve)

    Phillips-Perron Unit Root Test

data:  approve
Dickey-Fuller = -2.8387, Truncation lag parameter = 3, p-value = 0.235
adf.test(approve)

    Augmented Dickey-Fuller Test

data:  approve
Dickey-Fuller = -3.9565, Lag order = 3, p-value = 0.01721
alternative hypothesis: stationary
PP.test(avg.price)

    Phillips-Perron Unit Root Test

data:  avg.price
Dickey-Fuller = -2.3318, Truncation lag parameter = 3, p-value = 0.4405
adf.test(avg.price)

    Augmented Dickey-Fuller Test

data:  avg.price
Dickey-Fuller = -3.0115, Lag order = 3, p-value = 0.1649
alternative hypothesis: stationary

Differencing the Time Series

Recall that we can use differencing to address the issue of nonstationarity.

We can difference a random walk as follows:

\[ \begin{aligned} y_{t} =& y_{t-1} + \boldsymbol{x_t \beta} + e_t \\ y_{t}-y_{t-1} =& y_{t-1} - y_{t-1} + \boldsymbol{x_t \beta} + e_t \\ \Delta y_t =& \boldsymbol{x_t\beta}+e_t \end{aligned} \]

The result is AR(0) and stationary.

But note that we are now explaining the short run difference not the level.

Unit Root Tests after Differencing

approve
 [1] 58.67 58.00 60.50 55.00 54.00 56.50 56.00 75.67 88.00 87.00 86.00 83.67
[13] 82.00 79.25 76.25 76.33 73.40 70.50 66.50 67.20 64.75 66.33 62.75 60.17
[25] 58.75 65.20 70.00 66.33 62.00 59.67 59.50 51.00 54.67 51.67 58.50 55.25
[37] 51.33 50.67 52.00 47.33 48.50 47.75 50.00 52.67 49.17 54.00 51.00 51.67
[49] 52.25 49.67 48.50 48.00 46.25 47.33 43.75 44.00 40.75 38.33 42.25 43.00
[61] 39.67 36.50 35.67 37.00 40.00
diff(approve) # get an order-1 differenced time series
 [1] -0.67  2.50 -5.50 -1.00  2.50 -0.50 19.67 12.33 -1.00 -1.00 -2.33 -1.67
[13] -2.75 -3.00  0.08 -2.93 -2.90 -4.00  0.70 -2.45  1.58 -3.58 -2.58 -1.42
[25]  6.45  4.80 -3.67 -4.33 -2.33 -0.17 -8.50  3.67 -3.00  6.83 -3.25 -3.92
[37] -0.66  1.33 -4.67  1.17 -0.75  2.25  2.67 -3.50  4.83 -3.00  0.67  0.58
[49] -2.58 -1.17 -0.50 -1.75  1.08 -3.58  0.25 -3.25 -2.42  3.92  0.75 -3.33
[61] -3.17 -0.83  1.33  3.00
diff(approve, differences = 2) # order-2 differenced time series
 [1]   3.17  -8.00   4.50   3.50  -3.00  20.17  -7.34 -13.33   0.00  -1.33
[11]   0.66  -1.08  -0.25   3.08  -3.01   0.03  -1.10   4.70  -3.15   4.03
[21]  -5.16   1.00   1.16   7.87  -1.65  -8.47  -0.66   2.00   2.16  -8.33
[31]  12.17  -6.67   9.83 -10.08  -0.67   3.26   1.99  -6.00   5.84  -1.92
[41]   3.00   0.42  -6.17   8.33  -7.83   3.67  -0.09  -3.16   1.41   0.67
[51]  -1.25   2.83  -4.66   3.83  -3.50   0.83   6.34  -3.17  -4.08   0.16
[61]   2.34   2.16   1.67
diff(approve) |> adf.test()

    Augmented Dickey-Fuller Test

data:  diff(approve)
Dickey-Fuller = -4.3461, Lag order = 3, p-value = 0.01
alternative hypothesis: stationary
diff(avg.price) |> adf.test()

    Augmented Dickey-Fuller Test

data:  diff(avg.price)
Dickey-Fuller = -5.3361, Lag order = 3, p-value = 0.01
alternative hypothesis: stationary

Forecasting with a Non-stationary Time Series

As explained in the lecture (Topic 4), we estimate an ARIMA(0,1,0) which fits a little better than ARIMA(2,1,2) on the AIC criterion.

xcovariates <- cbind(sept.oct.2001, iraq.war, avg.price)
arima.res1a <- arima(approve, order = c(0,1,0),
                     xreg = xcovariates, include.mean = TRUE)
print(arima.res1a)

Call:
arima(x = approve, order = c(0, 1, 0), xreg = xcovariates, include.mean = TRUE)

Coefficients:
      sept.oct.2001  iraq.war  avg.price
            11.2072    5.6899    -0.0710
s.e.         2.5192    2.4891     0.0337

sigma^2 estimated as 12.35:  log likelihood = -171.25,  aic = 350.5
pe.1a <- arima.res1a$coef                    # parameter estimates (betas)
se.1a <- sqrt(diag(arima.res1a$var.coef))    # standard errors
ll.1a <- arima.res1a$loglik                  # log likelihood at its maximum
sigma2hat.1a <- arima.res1a$sigma2           # standard error of the regression
aic.1a <- arima.res1a$aic                    # Akaike Information Criterion
resid.1a <- arima.res1a$resid                # residuals

Forecasting with a Non-stationary Time Series

Some counterfactual stories might help….

  • What if 9/11 had not happened?
  • What if Bush had not invaded Iraq?
  • What if the price of oil had remained at pre-war levels?

Step 1: construct counterfactual scenarios

xhyp_no911 <- xcovariates[8:65, ]
xhyp_no911[, "sept.oct.2001"] <- 0
xhyp_noiraq <- xcovariates[26:65, ]
xhyp_no911[, "iraq.war"] <- 0
xhyp_oilprewar <- xcovariates[26:65, ]
xhyp_oilprewar[, "avg.price"] <- xcovariates[25, "avg.price"]

Step 2: Generate Predicted Values and Prediction Intervals

approve_no911 <- predict(arima.res1a, newxreg = xhyp_no911) # predict after september 2001; it will return a list containing expected predictions and standard errors of predictions
# construct a data.frame for plot
pred_no911 <- tibble::tibble(
  mean = c(approve[1:7], approve_no911$pred),
  se = c(rep(0, 7), rep(approve_no911$se, 65-8+1)),
  lwr = mean - 1.96*se, # we can use se here to construct lwr because we use tibble; you cannot do this if you use `data.frame()`
  upr = mean + 1.96*se
)
DT::datatable(pred_no911)
# let's see how it goes compared to original time series
plot(ts(approve, start = c(2001, 2), frequency = 12))
lines(ts(c(approve[7], approve_no911$pred), start = c(2001, 8), frequency = 12), lty = "dashed")

Step 3: Simulate Expected Values and Confidence Intervals

# First we need the simulated parameters
sims <- 1e4
simparams <- mvrnorm(n = sims, mu = arima.res1a$coef, Sigma = arima.res1a$var.coef)
head(simparams)
     sept.oct.2001 iraq.war   avg.price
[1,]     11.649601 4.860208 -0.08968427
[2,]     10.247836 7.708647 -0.12007851
[3,]     10.496385 3.453586 -0.11802825
[4,]     13.960427 4.222131 -0.10841761
[5,]      8.864249 4.779448 -0.14912944
[6,]     10.268829 6.609946 -0.08939397
dim(simparams)
[1] 10000     3
sim_approve <- matrix(NA, nrow = sims, ncol = 65 - 8 + 1)
model <- arima.res1a
for (i in 1:sims) {
  model$coef <- simparams[i, ]
  sim_approve[i, ] <- predict(model, newxreg = xhyp_no911)[["pred"]]
}
dim(sim_approve)
[1] 10000    58
exp_no911 <- data.frame(
  mean = c(approve[1:7], colMeans(sim_approve)),
  lwr = c(approve[1:7], apply(sim_approve, 2, quantile, 0.025)),
  upr = c(approve[1:7], apply(sim_approve, 2, quantile, 0.975))
)

Step 4: Plot!!!

library(tidyverse)
plot_data <- bind_rows(pred_no911, exp_no911, .id = "type")
plot_data$time <- paste0(approval$year, "-",approval$month) |> lubridate::ym() |> rep(2)
ggplot(plot_data, aes(x = time, y = mean, ymax = upr, ymin = lwr)) +
  geom_line() +
  geom_ribbon(aes(fill = type), alpha = 0.3) +
  labs(x = "Time", y = "Approval Rate") +
  theme_classic()

Cointegration Analysis

Thus far, we have been examining a single time series with covariates. This assumes that there is no feedback between variables.

Yet, we may be interested in the relationship between two potentially nonstationary time series that influence each other.

The original idea behind cointegration is that two time series may be in equilibrium in the long run but in the short run the two series deviate from that equilibrium.

Cointegrated time series are two nonstationary time series that are causally connected and do not tend toward any particular level but tend toward each other.

Cointegration means that a specific combination of two nonstationary series may be stationary. We say that these two series are cointegrated and the vector that defines the stationary linear combination is called the cointegrating vector.

More on ECM Applications in political science: Grant and Leob (2016)

Cointegration Analysis: Engle-Granger Two Step - Step 1

set.seed(98105)

# Generate cointegrated data
e1 <- rnorm(100)
x <- cumsum(e1) # x is a cumulative sum of e1, so it must be non-stationary
e2 <- rnorm(100)
y <- 0.6*x + e2 # define the relationship between x and y. They are both non-stationary

#Run step 1 of the Engle-Granger two step
coint.reg <- lm(y ~ x - 1)              
#Estimate the cointegration vector by least squares with no constant
coint.err <- residuals(coint.reg)       
#This gives us the cotingeration vector.

#Check for stationarity of the cointegration vector
adf.test(coint.err)$statistic |> # get the test statistic of ADF test
  punitroot(trend="nc") # punitroot() comes from urca package. it compute the cumulative probability of the ACF test statistic. "nc" means it is a test for regression without intercept (see ?urca::punitroot)
Dickey-Fuller 
 1.835502e-06 
#Make the lag of the cointegration error term
coint.err.lag <- coint.err[1:(length(coint.err)-2)]

#Make the difference of y and x
dy <- diff(y)
dx <- diff(x)

#And their lags
dy.lag <- dy[1:(length(dy)-1)]
dx.lag <- dx[1:(length(dx)-1)]

#Delete the first dy, because we are missing lags for this obs
dy <- dy[2:length(dy)]

Cointegration Analysis: Engle-Granger Two Step - Step 2

#Estimate an Error Correction Model with LS
ecm1 <- lm(dy ~ coint.err.lag + dy.lag + dx.lag)
summary(ecm1)

Call:
lm(formula = dy ~ coint.err.lag + dy.lag + dx.lag)

Residuals:
     Min       1Q   Median       3Q      Max 
-3.05134 -0.64656  0.02462  0.76963  2.04272 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    0.08009    0.11676   0.686    0.494    
coint.err.lag -0.89254    0.14294  -6.244 1.22e-08 ***
dy.lag        -0.85110    0.11222  -7.584 2.36e-11 ***
dx.lag         0.56191    0.13088   4.293 4.28e-05 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.152 on 94 degrees of freedom
Multiple R-squared:  0.4014,    Adjusted R-squared:  0.3822 
F-statistic: 21.01 on 3 and 94 DF,  p-value: 1.688e-10

Cointegration Analysis: Johansen Estimator

#Alternatively, we can use the Johansen estimator
#Create a matrix of the cointegrated variables
cointvars <- cbind(y,x)
# Perform cointegration tests
coint.test1 <- ca.jo(cointvars,
                   ecdet = "const",
                   type="eigen",
                   K=2,
                   spec="longrun")
summary(coint.test1)

###################### 
# Johansen-Procedure # 
###################### 

Test type: maximal eigenvalue statistic (lambda max) , without linear trend and constant in cointegration 

Eigenvalues (lambda):
[1] 3.520082e-01 2.399643e-02 1.460788e-17

Values of teststatistic and critical values of test:

          test 10pct  5pct  1pct
r <= 1 |  2.38  7.52  9.24 12.97
r = 0  | 42.52 13.75 15.67 20.20

Eigenvectors, normalised to first column:
(These are the cointegration relations)

               y.l2      x.l2   constant
y.l2      1.0000000  1.000000  1.0000000
x.l2     -0.5565254 -4.955866  0.4169868
constant -0.2979546 32.290892 32.4988636

Weights W:
(This is the loading matrix)

           y.l2        x.l2      constant
y.d -0.92569359 0.003754100 -1.582064e-17
x.d  0.02021318 0.007824302 -4.297376e-18
ecm.res1 <- cajorls(coint.test1,
                    r = 1,           # Cointegration rank
                    reg.number = 1)  # which variable(s) to put on LHS
#(column indexes of cointvars)
summary(ecm.res1)
     Length Class  Mode   
rlm  12     lm     list   
beta  3     -none- numeric

Cointegration Analysis

#For the presidential approval example, use an ECM equivalent to the
#ARIMA(1,0,1) model that we chose earlier

cointvars <- cbind(approve,avg.price)
ecm.test1 <- ca.jo(cointvars,
                   ecdet = "const",
                   type="eigen",
                   K=2,
                   spec="longrun",
                   dumvar=cbind(sept.oct.2001,iraq.war))
summary(ecm.test1)

###################### 
# Johansen-Procedure # 
###################### 

Test type: maximal eigenvalue statistic (lambda max) , without linear trend and constant in cointegration 

Eigenvalues (lambda):
[1] 2.391542e-01 1.367744e-01 1.387779e-16

Values of teststatistic and critical values of test:

          test 10pct  5pct  1pct
r <= 1 |  9.27  7.52  9.24 12.97
r = 0  | 17.22 13.75 15.67 20.20

Eigenvectors, normalised to first column:
(These are the cointegration relations)

              approve.l2 avg.price.l2 constant
approve.l2     1.0000000    1.0000000  1.00000
avg.price.l2   0.1535049    0.3382829 -1.05616
constant     -76.0019182 -120.7778161 90.24200

Weights W:
(This is the loading matrix)

             approve.l2 avg.price.l2     constant
approve.d   -0.12619985   0.02231967 5.407866e-17
avg.price.d -0.02220281  -0.58771490 3.727850e-16
ecm.res1 <- cajorls(ecm.test1,
                    r = 1,
                    reg.number = 1)
summary(ecm.res1$rlm)

Call:
lm(formula = substitute(form1), data = data.mat)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.1403 -1.6753 -0.2261  1.6430  5.9537 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
ect1          -0.12620    0.03006  -4.198 9.37e-05 ***
sept.oct.2001 19.55846    2.11737   9.237 5.40e-13 ***
iraq.war       5.01870    1.62432   3.090  0.00307 ** 
approve.dl1   -0.31757    0.09448  -3.361  0.00138 ** 
avg.price.dl1 -0.05055    0.02593  -1.949  0.05613 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.668 on 58 degrees of freedom
Multiple R-squared:  0.6301,    Adjusted R-squared:  0.5983 
F-statistic: 19.76 on 5 and 58 DF,  p-value: 1.915e-11

Cointegration Analysis

#Cointegration analysis with a spurious regressor
phony <- rnorm(length(approve))
for (i in 2:length(phony)){
    phony[i] <- phony[i-1] + rnorm(1) 
}

cointvars <- cbind(approve,avg.price,phony)

ecm.test1 <- ca.jo(cointvars,
                   ecdet = "const",
                   type="eigen",
                   K=2,
                   spec="longrun",
                   dumvar=cbind(sept.oct.2001,iraq.war))
summary(ecm.test1)

###################### 
# Johansen-Procedure # 
###################### 

Test type: maximal eigenvalue statistic (lambda max) , without linear trend and constant in cointegration 

Eigenvalues (lambda):
[1] 2.522926e-01 2.289387e-01 7.351248e-02 4.440892e-16

Values of teststatistic and critical values of test:

          test 10pct  5pct  1pct
r <= 2 |  4.81  7.52  9.24 12.97
r <= 1 | 16.38 13.75 15.67 20.20
r = 0  | 18.32 19.77 22.00 26.81

Eigenvectors, normalised to first column:
(These are the cointegration relations)

               approve.l2 avg.price.l2     phony.l2     constant
approve.l2     1.00000000    1.0000000   1.00000000   1.00000000
avg.price.l2   0.09303864    0.6851653  -0.03481344   0.07966019
phony.l2       1.00806669   -3.8070344  -0.83878975   3.65291691
constant     -69.12999967 -160.7372332 -59.59236067 -92.56171519

Weights W:
(This is the loading matrix)

             approve.l2 avg.price.l2     phony.l2      constant
approve.d   -0.12669497  0.009643857 -0.003510338  6.872469e-16
avg.price.d  0.03091869 -0.420502736 -0.053024935 -7.633789e-16
phony.d      0.01535096  0.012992853 -0.012809245 -1.347668e-16
ecm.res1 <- cajorls(ecm.test1,
                    r = 1,
                    reg.number = 1)
summary(ecm.res1$rlm) 

Call:
lm(formula = substitute(form1), data = data.mat)

Residuals:
    Min      1Q  Median      3Q     Max 
-6.9919 -1.5593 -0.1705  1.7087  6.4629 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
ect1          -0.12669    0.02919  -4.340 5.90e-05 ***
sept.oct.2001 19.10637    2.11016   9.054 1.26e-12 ***
iraq.war       5.52734    1.65178   3.346  0.00145 ** 
approve.dl1   -0.32650    0.09473  -3.447  0.00107 ** 
avg.price.dl1 -0.04073    0.02578  -1.580  0.11972    
phony.dl1      0.12774    0.31229   0.409  0.68404    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.664 on 57 degrees of freedom
Multiple R-squared:  0.6377,    Adjusted R-squared:  0.5996 
F-statistic: 16.72 on 6 and 57 DF,  p-value: 5.14e-11