4

We all understand that the Granger Causality test entails constructing two models. The first one is simply an autoregressive model with $y_{t-1}$ being the single independent variable. The second one is adding an $x_{t-1}$ to the autoregressive model. Next, you check whether the residuals of those two models are different using an $F$-test. If they are, you can say that $x$ Granger-causes $y$.

However, within the "vars" package in R, when you use the causality function it works differently. That's because you can only specify what is $x$. The package's author calls it a "cause" variable. But you can't specify what is $y$, or the response variable. So when the R output comes out, you get that $x$ Granger-causes several different variables simultaneously with one single given $p$-value.

Within the framework of Granger Causality as depicted above, this does not seem to make much sense. I can understand variable $A$ Granger-causes variable $B$. But I don't understand how variable $A$ Granger-causes variables $B$, $C$, $D$ with a single $p$-value estimate just as if you had done $A$ Granger-causes $B$ alone.

Sympa
  • 6,862
  • 3
  • 30
  • 56
  • Can you post a reproducible example? My guess would be it means "A causes at least one of B, C, D." – Christoph Hanck Dec 21 '15 at 04:46
  • Christoph, I am attempting to copy the output I have copied from R onto an Excel spreadsheet. I don't know if I'll have much success with that. Granger-causality testing Personal Income granger causing H6DDA growth. > causality(var3, cause = "pi", vcov. = NULL, boot = FALSE, boot.runs=100) $Granger Granger causality H0: pi do not Granger-cause h6dda ten data: VAR object var3 F-Test = 5.7548, df1 = 4, df2 = 606, p-value = 0.0001501 – Sympa Dec 21 '15 at 19:39
  • The most important section of the R output above is: "Granger causality HO: pi do not Granger-cause h6dda ten. pi stands for Personal Income, h6dda is Deposit (time series DDA with H6 money aggregates) and ten stands for 10 Year Treasury. In other words, this Granger-causality test tests whether Personal income (the cause in the coding of the R function) Granger-cause Deposit growth and also 10 Year Treasury movements... which does not make much sense to me. – Sympa Dec 21 '15 at 19:45
  • Please edit your original question - this is fairly hard to read. Also, this is not reproducible, just the output. – Christoph Hanck Dec 22 '15 at 08:51
  • Someone else already edited my question. I am not too sure how to edit it further. Given the issue, it is reasonably well described. The issue in a nutshell is very simple. We all understand how Variable A Granger-causes Variable B (I have described the mechanics of Granger Causality testing above). But, what does Variable A Granger-causes Variables B, C, and D at the same time mean? I argue that there is a bug in this causality() function. And, it is missing an argument. You should be able to select the variable that is affected. – Sympa Dec 22 '15 at 18:11

4 Answers4

3

When I first used the causality function of the vars package I had the same doubt. Here is what I thought.

Imagine a trivariate VAR(1) model:

$$ Y_t = a_0 + a_1 Y_{t-1} + a_2 X_{t-1} + a_3 Z_{t-1} + \epsilon_{y,t} \\ X_t = b_0 + b_1 Y_{t-1} + b_2 X_{t-1} + b_3 Z_{t-1} + \epsilon_{x,t} \\ Z_t = c_0 + c_1 Y_{t-1} + c_2 X_{t-1} + c_3 Z_{t-1} + \epsilon_{z,t} $$

In order to $X_t$ not Granger cause $Y_t$ you need to make sure that $H_0: a_2 = a_3 = 0$ or $H_0: a_2 = c_2 = 0$. You can build an $F$-test for that, but what the causality function seems to be doing is checking if $X_t$ Granger causes all other variables in the model. Why would they do that? Maybe because it is simpler. That would be the same as to just check if $H_0: a_2 = c_2 = 0$. This is a much more simple $F$-test, and it extends easily to more than three variables. So, if I am correct, this is not a bug, they simple took the easiest path. So if the null is not rejected, this means that $X_t$ does not Granger cause $Y_t$ and $Z_t$. But if the null is rejected, the test doesn't say much, $X_t$ may be Granger causing either $Y_t$, $Z_t$ or both.

Note that in the help of the causality function they only show a bivariate case, but from that example you can infer that the trivariate case would be as I described. To make sure that this is the case, one can build the corresponding $F$-test and check if the values are equal. Also, if you want to specify the response variable you can use the grangertest function of the lmtest package.

Regis A. Ely
  • 831
  • 7
  • 14
  • 2
    Regis, thanks that's a pretty good answer. I am not entirely comfortable with the Granger causality framework as depicted. It would seem way too noisy. I actually really like your suggestion of using granger test () within the lmtest package. That most probably implements Granger causality in a well established fashion. – Sympa Jan 26 '16 at 22:27
1

An workaround to test cause and response within the vars pkg with the help of the "exogen" settings in the VAR function:

granger_bivariate <- function(varest, causal, dep){
  dtmat <- varest$datamat
  mat_target <- dtmat[, c(causal, dep)]
  other_as_exo <- dtmat[, setdiff(names(dtmat),c(causal, dep,'const',names(dtmat)[grepl(paste0('^',causal),names(dtmat)) | grepl(paste0('^',dep),names(dtmat)) ]))]
  var_target <- VAR(mat_target, p = varest$p, exogen = other_as_exo)
  gr_target <- causality(var_target, cause = causal)
  g1 <- gr_target$Granger
  result <- cbind(g1$statistic[1,1], g1$p.value)
  return(result)
}

This works since the causality test ignore the variables in the exogen setting.

user241514
  • 11
  • 1
1

As Regis suggested, using the function grangertest from the package lmtest is a way to produce the pairwise test result. This should be equivalent to using the causality function from vars on a bivariate VAR model. In the following, the F-statistics are indentical, and the p-values are slightly different:

data(ChickEgg)

res1 = grangertest(egg ~ chicken, data = ChickEgg, order = 3)

res2 = causality(VAR(ChickEgg, p = 3), cause = 'chicken')

res1$F[2]

res1[4][2,]

res2$Granger$statistic

res2$Granger$p.value

For multivariate VAR, we can examine each pair of variables separately.

Long Vo
  • 111
  • 2
1

Another simple solution is the following:

    NAMES = colnames(df)
    k = ncol(df)
    for (j in 1:k) {
      for (i in 1:k) {
        if (i != j) {
          print(paste(NAMES[j], "->", NAMES[i]))
          VARest = vars::VAR(df[,c(j,i)], p=1)
          print(causality(VARest, cause=NAMES[j]))
        }
      }
    }
Nikosant
  • 11
  • 2