Search code examples
rggplot2plot

Plotting impulse response functions in grid format


I have run the following Impulse response functions from a VAR model in R

debtarg_1 <- irf(var.est.debt_arg,response="pfdebt_arg",impulse="sp",n.ahead=40,ortho=TRUE,boot=TRUE)
plot(debtarg_1) # response of pfdebt to s&p shock

debtarg_2 <- irf(var.est.debt_arg,response="pfdebt_arg",impulse="m1_us",n.ahead=40,ortho=TRUE,boot=TRUE)
plot(debtarg_2) # response of pfdebt to us M1 Shock

debtarg_3 <- irf(var.est.debt_arg,response="pfdebt_arg",impulse="m1_arg",n.ahead=40,ortho=TRUE,boot=TRUE)
plot(debtarg_3) # response of pfdebt to a domestic m1 shock

debtarg_4 <- irf(var.est.debt_arg,response="pfdebt_arg",impulse="eq_arg",n.ahead=40,ortho=TRUE,boot=TRUE)
plot(debtarg_4) # response of pfdebt to equity market price shock

debtarg_5 <- irf(var.est.debt_arg,response="pfdebt_arg",impulse="pfequity_arg",n.ahead=40,ortho=TRUE,boot=TRUE)
plot(debtarg_5) # response of pfdebt to pfequity shocks


I would like to plot all of these in grid format for a paper using ggplot and gridextra. Does anyone have any advice on how to reproduce this in grid format? I have plotted data in grid format before after reading it into R from an Excel file, however I am unsure of how to approach this with 5 seperate IRFs that I've run. I will attach my code for a grid plot I've made before and hopefully someone could assist me in tweaking this code to plot these 5 IRFs in a grid?

library(tidyverse)
library(tidyselect)
library(xtable)
library(readxl)
library(ggthemes)
library(ggsci)
library(gridExtra)

currentdata <- read_excel(path = "./data/current_gdp.xlsx",
                            col_names = T)

currentdata <- currentdata %>% gather(key = Countries, value = ca, -Date)


g1 <- ggplot(data = currentdata) + 
geom_line(aes(x = Date, y = ca, group = 1, colour = Countries), size = 1.3) + 
theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 90, hjust = 1)) +
scale_x_discrete(breaks = seq(1980, 2018, by = 5)) +  
labs(caption = "Source - World Bank (2019)", x = "", y = "Current Account (as a % of GDP)") + 
    facet_wrap(~Countries, scales = "free") + guides(color = FALSE)


print(g1)

UPDATE - I have included a sample of my dataset (debt_arg) below.

   sp    m1_us     m1_arg   eq_arg  pfdebt_arg pfequity_arg
 [1,]  43.090997 414955.4   1538.701   270.48   326000000            0
 [2,]  26.979045 410044.9   2398.424   265.24    21000000            0
 [3,]  16.967093 403034.4   2392.100   652.73    11000000            0
 [4,]  29.505141 412023.8   4133.943   800.62  7869000000            0
 [5,]   4.173189 422013.3   3777.726   747.79   862806000    321395635
 [6,]  -4.848764 418102.8   4867.334   660.42   538167500    -27163752
 [7,] -24.060716 435092.2   4108.552   419.80   476328500    578208609
 [8,] 755.186270 717496.6 -29574.420 33461.77 -1071543954   -130885582
 [9,] 363.624318 716186.1 -23324.997 30292.55  -728949104   -187033565
[10,] 664.462366 728275.5 -32336.032 33466.03   519284161    195110656

From this, I ran a VAR Model using the following line of code.

var.est.debt_arg <- VAR(debt_arg,p=1,type="both",season=NULL)
summary(var.est.debt_arg)

I would like to plot the 5 IRFs at the top all in the same row

from this

Thank you!


Solution

  • The plot you generate using the impulse model is using base R. Below is a possible solution. I cannot do the fit with your example, so I used something from the package:

    library(vars)
    library(cowplot)
    library(gridExtra)
    

    use example data Canada and run VAR:

    data(Canada)
    var.est.debt_arg <- VAR(Canada, p = 2, type = "both",season=NULL)
    

    define response and impulse variables

    RESPONSE = "prod"
    IMPULSE = c("e","U","rw")
    

    collect all your fits in a list:

    fits = lapply(IMPULSE,function(i){
    irf(var.est.debt_arg,response=RESPONSE,impulse=i,
    n.ahead=40,ortho=TRUE,boot=TRUE)
    })
    names(fits) = IMPULSE
    

    Iterate through the fits, generate the plot and capture it using as_grob

    P = lapply(fits,function(i)as_grob(~plot(i,cex.main=0.7,mar=c(0.5,0.5,0.5,0.5))))
    grid.arrange(grobs=P,ncol=3)
    

    enter image description here

    If you want to use ggplot, then:

    plotdf = lapply(names(fits),function(i){
    data.frame(
      index = 1:nrow(fits[[i]]$irf[[1]]),
      value=fits[[i]]$irf[[1]][,1],
      Lower=fits[[i]]$Lower[[1]][,1],
      Upper=fits[[i]]$Upper[[1]][,1],
      Impulse = i)
    })
    plotdf=do.call(rbind,plotdf)
    
    ggplot(plotdf,aes(x=index,y=value)) + 
    geom_line() +facet_wrap(~Impulse) + 
    geom_ribbon(aes(ymin=Lower,ymax=Upper),fill=NA,col="salmon",linetype="dashed") + 
    geom_hline(yintercept=0,col="salmon") + theme_bw()
    

    enter image description here