Analyzing the impact of a shock

Contents

2. Analyzing the impact of a shock#

When working with a model, it is often useful to have a quantitative sense of the contribution of different channels to a final result. For example, an increase in interest rates will tend to reduce investment and consumer demand – contributing to a reduction in GDP. At the same time, lower inflation as the higher interest rate takes effect will tend to work in the opposite direction.

The tracedep() and tracepre() methods introduced in the previous chapter give a sense of impacts. The ModelFlow methods .dekomp() and .totdif() take that one step further by calculating the contribution of each channel to the overall result.

In this chapter - Analyzing the Impact of a Shock

This chapter provides the tools and techniques to dissect and understand the ripple effects of shocks within macroeconomic systems.

This chapter focuses on methods to analyze the impacts of external shocks within a macroeconomic model. The previous chapter explored the impacts of changes in one variable on other variables in a model by following the causal chain of any individual variable.

The techniques explored in this chapter illustrate and extend this by:

  • attributing changes in any given model variable to the changes in the variables in the model that were shocked. In the techniques used in the previous chapter it may be determined that increased inflation was the proximate cause of a decline in consumption, the methods presented here seek to illuminate which of the changes to exogenous variables caused the increase in inflation that caused the decline in consumption (say an increase in oil prices).

  • Impacts can be traced either through a single equation method or using a model level decomposition

Examples include a range of graphical and textual visualization of results.

# set default precision 
pd.set_option("display.precision", 2)
# For display reasons 
latex = 1

2.1. Load the existing model, data and descriptions#

The file pak.pcim contains a dump of model equations, dataframe, simulation options and variable descriptions for the World Bank climate aware model for Pakistan described in Burns et al. [2021].

The code below:

  • Loads the model and simulates it using the DataFrame stored in the pcim file to establish a baseline.

  • Creates a DataFrame that is a copy (from 2020) of the active solution in mpak and changes the tax rate to 30 USD/Ton for carbon emissions from coal, oil and natural gas.

  • Runs a simulations with these new carbon taxes.

The results from this simulation will be used below to explore the attribution functionality of ModelFlow.

Single equation Impact Decomposition

mpak,baseline = model.modelload('../models/pak.pcim',alfa=0.7,run=1,relconv=0.0000000001 ,keep='Business as Usual')
alternative  =  baseline.upd("<2020 2100> PAKGGREVCO2CER PAKGGREVCO2GER PAKGGREVCO2OER = 30")
Zipped file read:  ..\models\pak.pcim
#simulate the model
result = mpak(alternative,2025,2100,keep='Nominal carbon tax of 30 USD',
              ljit=False,         # do not compile the model (default value for this option)
              nfirst=800,
              maxiteration=100   # if no convergence after 100 iterations - stop
             ) # simulates the model 

2.2. The mathematics of decomposition#

At its root the idea of attribution is to take the total derivative of the model to identify the sensitivity of the equation of interest to changes elsewhere in the model and then combine that with the changes in other variables.

Take a variable y that is a function of two other variables a and b. In the model, the relationship might be written as:

\(y = f(a,b)\)

If there are two sets of results designated with a subscript 0 and 1, these can be written as:

(2.1)#\[\begin{eqnarray} y_0 = f(a_0,b_0)\\ y_1 = f(a_1,b_1) \end{eqnarray}\]

If the change in the three variables is specified as \(\Delta y, \Delta a, \Delta b\), the total derivative of y can be written as:

\(\Delta y = \underbrace{\Delta a \dfrac{\partial {f}}{\partial{a}}(a,b)}_{\Omega a} + \underbrace{\Delta b \dfrac{\partial {f}}{\partial{b}}(a,b)}_{\Omega b}+Residual\)

The first expression can be called \(\Omega_a\) or the contribution of changes in a to changes in y, and the second \(\Omega_b\), or the contribution of changes in b to changes in y.

ModelFlow performs a numerical approximation of \(\Omega_a\) and \(\Omega_b\) by performing two runs of the \(f()\):

(2.2)#\[\begin{eqnarray} y_0&=&f(a_{0},b_{0}) \\ y_1&=&f(a_0+\Delta a,b_{0}+ \Delta b) \end{eqnarray}\]

and calculates \(\Omega_a\) and \(\Omega_b\) as:

(2.3)#\[\begin{eqnarray} \Omega a&=&f(a_1,b_1 )-f(a_1-\Delta a,b_1) \\ \Omega b&=&f(a_1,b_1 )-f(a_1,b_1-\Delta b) \end{eqnarray}\]

And:

(2.4)#\[\begin{eqnarray} residual = \Omega a + \Omega b -(y_1 - y_0) \end{eqnarray}\]

If the model is fairly linear, the residual will be small.

2.3. Model-level decomposition or single equation decomposition?#

Above, the relationship between y, a, and b was summarized by the function f().

\(f(a,b)\) could represent a single equation in the model or it could represent the entire model.

In the single equation mode, \(\Delta a\) and \(\Delta b\) would be treated as exogenous variables in the attribution calculation as they are both on the right hand side of the equation (i.e. exogenous to this equation – even if they might be endogenous variables in some other equation). Here results will show the direct impact of changes in the RHS variable(s) on the LHS variable.

When analyzing the total derivative for the entire model instance, \(a\) and \(b\) will be purely exogenous variables. In this case, the decomposition shows the cumulative effect – potentially operating through multiple channels of a change in the exogenous (or exogenized variables) on different endogenous variables in the model. Say we are looking at inflation, an exogenous change in wages would influence prices directly through higher costs of production and indirectly by inducing higher demand. The model-level decompoistion will return the sum of the two or more influences.

Assume the simple equation example such that \(a\) and \(b\) are simple variables. When \(\Delta y\), \(\Delta a\) and \(\Delta b\) reflect the difference across scenarios (say the value of the three variables in .lastdf less the value in .basedf) then;

\(\Omega_a\), \(\Omega_b\) are the absolute contribution of a and b to the change in y, and \(100*\bigg[\cfrac{\Omega_a}{\Delta y}\bigg]\) is the share of the change in y explained by expressed as a percent and \(100*\bigg[\cfrac{\Omega_b}{\Delta y}\bigg]\) is the share of the change in y explained by b expressed as a percent.

If \(\Delta y\), \(\Delta a\) and \(\Delta b\) are the changes over time (\(\Delta y_t=y_t-y_{t-1}\)), then \(\Omega_a\), \(\Omega_b\) are the contributions of a and b to the rate of growth of y, while \(100*\bigg[\cfrac{\Omega_a}{\Delta y_{t-1}}\bigg]\) \(100*\bigg[\cfrac{\Omega_b}{\Delta y_{t-1}}\bigg]\) are are the contributions of a and b to the rate of growth of y.

2.4. Decomposing the source of changes to a single endogenous variable#

The ModelFlow method .dekomp() is used to calculate the contribution of RHS variables to the change in an endogenous (LHS) variable.

This method takes advantage of the fact that the model object stores the initial and most recent simulation result in two dataframes called .basedf and .lastdf, as well as all of the equations of the model.

The dekomp() method calculates the contribution to changes in the level of the dependent variable in a given equation. It does not calculate what caused the changes to the RHS variables.

In the example below, the contribution to the change in Total emissions is decomposed into the contribution from each of three sources in the model, the consumption of Crude Oil, Natural Gas and Coal. As the equation for total emissions is just the sum of the three this is a fairly trivial decomposition, but it provides an easily understood illustration of the process at work.

Note that, initially some carbon taxes were negative because the associated energy products benefited from some sort of subsidy. As a result, although each carbon tax is set to 30 in the simulation that was run earlier, the change in the levels of the Carbon tax is different across carbon taxes, with the increase in the net taxation on the carbon emissions from natural gas being particularly large.

print("Change in carbon taxes:") 
with mpak.set_smpl(2023,2030):
    print(mpak['PAKGGREVCO2CER PAKGGREVCO2GER PAKGGREVCO2OER'].dif.rename().df)
Change in carbon taxes:
      Carbon tax on coal (USD/t)  Carbon tax on gas (USD/t)  \
2023                       35.55                       71.0   
2024                       35.55                       71.0   
2025                       35.55                       71.0   
2026                       35.55                       71.0   
2027                       35.55                       71.0   
2028                       35.55                       71.0   
2029                       35.55                       71.0   
2030                       35.55                       71.0   

      Carbon tax on oil (USD/t)  
2023                      38.71  
2024                      38.71  
2025                      38.71  
2026                      38.71  
2027                      38.71  
2028                      38.71  
2029                      38.71  
2030                      38.71  
dekomp_result = mpak.PAKCCEMISCO2TKN.dekomp(start=2024,end=2027);
Formula        : FRML <IDENT> PAKCCEMISCO2TKN = PAKCCEMISCO2CKN+PAKCCEMISCO2OKN+PAKCCEMISCO2GKN $ 

                        2024         2025         2026         2027
Variable    lag                                                    
Base        0   230370296.36 236240661.98 242537408.00 248995663.61
Alternative 0   230370296.36 183872963.10 190234954.74 196979009.56
Difference  0           0.00 -52367698.88 -52302453.26 -52016654.05
Percent     0          -0.00       -22.17       -21.56       -20.89

 Contributions to difference for  PAKCCEMISCO2TKN
                          2024         2025         2026         2027
Variable        lag                                                  
PAKCCEMISCO2CKN 0         0.00 -22807768.70 -22763629.77 -22643891.23
PAKCCEMISCO2OKN 0         0.00 -13105358.04 -13576625.98 -13868109.25
PAKCCEMISCO2GKN 0         0.00 -16454572.13 -15962197.50 -15504653.56

 Share of contributions to difference for  PAKCCEMISCO2TKN
                     2024       2025       2026       2027
Variable        lag                                       
PAKCCEMISCO2CKN 0                44%        44%        44%
PAKCCEMISCO2GKN 0                31%        31%        30%
PAKCCEMISCO2OKN 0                25%        26%        27%
Total           0       0       100%       100%       100%
Residual        0    -100        -0%         0%        -0%

 Difference in growth rate PAKCCEMISCO2TKN
                      2024       2025       2026       2027
Variable    lag                                            
Base        0         2.3%       2.5%       2.7%       2.7%
Alternative 0         2.3%     -20.2%       3.5%       3.5%
Difference  0         0.0%     -22.7%       0.8%       0.9%
None

 Contribution to growth rate PAKCCEMISCO2TKN
                          2024       2025       2026       2027
Variable        lag                                            
PAKCCEMISCO2CKN 0         0.0%      -9.9%       0.4%       0.4%
PAKCCEMISCO2OKN 0         0.0%      -5.7%      -0.0%       0.1%
PAKCCEMISCO2GKN 0         0.0%      -7.1%       0.5%       0.5%
Total           0         0.0%     -22.7%       0.9%       1.0%
Residual        0         0.0%       0.0%       0.1%       0.1%

The above results from the call to .dekomp() are presented in several sections.

Section

Table

Contents

The first section

the normalized formula of the RHS variable PAKCCEMISCO2TKN

The second section

Shows the changes in level terms.

diff_level

First by showing the results of the simulation base, then the previous level last, then the difference and then the difference expressed as a percent

att_level

This is followed by a table showing the contribution of the changes in every LHS variable to the observed change in the dependent variable.

The third section

att_pct

Shows the same results for the RHS variables, but expressed as a percent of the total change in the dependent variable.

The fourth section

Shows the same results but for the change in the growth rate of the dependent variable.

diff_growth

The first table shows the post-shock growth rate of the dependent variable from the .lastdf dataframe, followed by the pre-shock growth rate and the difference in the growth rates.

att_growth

The second table of this section shows the contribution to the change in the growth rate from each RHS variable.

The object returned by .dekomp() is a namedtuple that contains each of these tables which can then be referred to later.

The code below extracts the different sub-components of the .dekomp() results and displays them individually.

# Loop over the elements in the result of dekomp. 
# a named tuple can be used both as a straight tuple and the elements
# can be accessed through the field name. 

with pd.option_context('display.float_format', '{:.2f}'.format):
    for f,df in zip(dekomp_result._fields,dekomp_result):
        display(f)
        display(df)
    
'diff_level'
2024 2025 2026 2027
Variable lag
Base 0 230370296.36 236240661.98 242537408.00 248995663.61
Alternative 0 230370296.36 183872963.10 190234954.74 196979009.56
Difference 0 0.00 -52367698.88 -52302453.26 -52016654.05
Percent 0 -0.00 -22.17 -21.56 -20.89
'att_level'
2024 2025 2026 2027
Variable lag
PAKCCEMISCO2CKN 0 0.00 -22807768.70 -22763629.77 -22643891.23
PAKCCEMISCO2OKN 0 0.00 -13105358.04 -13576625.98 -13868109.25
PAKCCEMISCO2GKN 0 0.00 -16454572.13 -15962197.50 -15504653.56
'att_pct'
2024 2025 2026 2027
Variable lag
PAKCCEMISCO2CKN 0 NaN 43.55 43.52 43.53
PAKCCEMISCO2GKN 0 NaN 31.42 30.52 29.81
PAKCCEMISCO2OKN 0 NaN 25.03 25.96 26.66
Total 0 0.00 100.00 100.00 100.00
Residual 0 -100.00 -0.00 0.00 -0.00
'diff_growth'
2024 2025 2026 2027
Variable lag
Base 0 2.27 2.55 2.67 2.66
Alternative 0 2.27 -20.18 3.46 3.55
Difference 0 0.00 -22.73 0.79 0.88
'att_growth'
2024 2025 2026 2027
Variable lag
PAKCCEMISCO2CKN 0 0.00 -9.90 0.40 0.44
PAKCCEMISCO2OKN 0 0.00 -5.69 -0.01 0.09
PAKCCEMISCO2GKN 0 0.00 -7.14 0.53 0.50
Total 0 0.00 -22.73 0.92 1.02
Residual 0 0.00 0.00 0.13 0.14

2.5. A more complex example#

The above decomposition is fairly straight forward because the decomposed equation is a simple identity, where Total Emissions are just the sum of its three component parts: Total Carbon emissions = Emissions from Oil+ Emissions from Coal + Emissions from Natural Gas.

The following single-equation decomposition looks to the impact of the same shock (introduction of a carbon tax) on a different variable (inflation). The inflation equation is more complex and has more direct causal variables, so the decomposition is more interesting.

Recall the inflation equation is given by the .frml method for its normalized version and .eviews for its original specification. The equation for the consumer price level (PAKNECONPRVTXN) was originally specified in eviews as:

mpak['PAKNECONPRVTXN'].eviews
PAKNECONPRVTXN : 
@IDENTITY PAKNECONPRVTXN  = ((PAKNECONENGYSH^PAKCESENGYCON)  * PAKNECONENGYXN^(1  - PAKCESENGYCON)  + (PAKNECONOTHRSH^PAKCESENGYCON)  * PAKNECONOTHRXN^(1  - PAKCESENGYCON))^(1  / (1  - PAKCESENGYCON))

The normalized equation is given by mpak['PAKNECONPRVTXN'].frml.

Note in the Pakistan model, consumer inflation is derived as a constant elasticity of transformation (CET) aggregation of the price of energy goods(PAKNECONENGYXN) and non-energy goods (PAKNECONOTHRXN).

mpak['PAKNECONPRVTXN'].frml
PAKNECONPRVTXN : FRML <IDENT> PAKNECONPRVTXN = ((PAKNECONENGYSH**PAKCESENGYCON)*PAKNECONENGYXN**(1-PAKCESENGYCON)+(PAKNECONOTHRSH**PAKCESENGYCON)*PAKNECONOTHRXN**(1-PAKCESENGYCON))**(1/(1-PAKCESENGYCON)) $

Note further the normalized equation is solving for the level of the price deflator – not inflation which is the rate of growth of this index.

Because the equation solves for the level of the price deflator, the decomposition show the contributions of each explanatory variable to the increase in the price level (not that of the inflation rate). However, the 4th table is showing the impacts on the rate of growth of the price level – i.e. the level of inflation.

mpak['PAKNECONPRVTXN'].dekomp(start=2024,end=2027);
Formula        : FRML <IDENT> PAKNECONPRVTXN = ((PAKNECONENGYSH**PAKCESENGYCON)*PAKNECONENGYXN**(1-PAKCESENGYCON)+(PAKNECONOTHRSH**PAKCESENGYCON)*PAKNECONOTHRXN**(1-PAKCESENGYCON))**(1/(1-PAKCESENGYCON)) $ 

                      2024       2025       2026       2027
Variable    lag                                            
Base        0         2.30       2.45       2.60       2.75
Alternative 0         2.30       2.51       2.68       2.83
Difference  0         0.00       0.06       0.07       0.08
Percent     0        -0.00       2.47       2.74       2.92

 Contributions to difference for  PAKNECONPRVTXN
                         2024       2025       2026       2027
Variable       lag                                            
PAKNECONENGYSH 0        -0.00      -0.00      -0.00      -0.00
PAKCESENGYCON  0        -0.00      -0.00      -0.00      -0.00
PAKNECONENGYXN 0        -0.00       0.01       0.01       0.01
PAKNECONOTHRSH 0        -0.00      -0.00      -0.00      -0.00
PAKNECONOTHRXN 0        -0.00       0.05       0.06       0.07

 Share of contributions to difference for  PAKNECONPRVTXN
                    2024       2025       2026       2027
Variable       lag                                       
PAKNECONOTHRXN 0                77%        81%        83%
PAKNECONENGYXN 0                23%        20%        18%
PAKNECONENGYSH 0                -0%        -0%        -0%
PAKCESENGYCON  0                -0%        -0%        -0%
PAKNECONOTHRSH 0                -0%        -0%        -0%
Total          0       0       100%       100%       100%
Residual       0    -100         0%         0%         0%

 Difference in growth rate PAKNECONPRVTXN
                      2024       2025       2026       2027
Variable    lag                                            
Base        0         7.3%       6.7%       6.2%       5.8%
Alternative 0         7.3%       9.3%       6.5%       6.0%
Difference  0         0.0%       2.6%       0.3%       0.2%
None

 Contribution to growth rate PAKNECONPRVTXN
                         2024       2025       2026       2027
Variable       lag                                            
PAKNECONENGYSH 0        -0.0%       0.0%      -0.0%      -0.0%
PAKCESENGYCON  0        -0.0%       0.0%      -0.0%      -0.0%
PAKNECONENGYXN 0        -0.0%       0.6%      -0.0%      -0.0%
PAKNECONOTHRSH 0        -0.0%       0.0%      -0.0%      -0.0%
PAKNECONOTHRXN 0        -0.0%       2.0%       0.3%       0.2%
Total          0        -0.0%       2.7%       0.3%       0.2%
Residual       0        -0.0%       0.0%      -0.0%      -0.0%

Interestingly only 23% of the increase in the price level each period is due to the direct channel (the impact on the price of energy consumed by households), the bulk of the increase comes indirectly through other prices. Indeed as time progresses this share rises from 77% in the first year of the price change (2020) to 83% by 2024.

2.5.1. Non-energy prices#

Below is the formula for nonenergy consumer prices and their decomposition. This equation is written out as a more standard augmented-phillips-curve type inflation equation reflecting changes in the cost of local goods production (PAKNYGDPFCSTXN), Government taxes on goods and services (PAKGGREVGNFSXN), the price of imports (PAKNEIMPGNGSXN) and the influence of the economic cycle (PAKNYGDPGAP_) on the price level.

mpak['PAKNECONOTHRXN'].eviews
PAKNECONOTHRXN : 
DLOG(PAKNECONOTHRXN) = 0.590372627657176*DLOG(PAKNYGDPFCSTXN) + D(PAKGGREVGNFSXN/100) + (1 - 0.590372627657176)*DLOG(PAKNEIMPGNFSXN) + 0.2*PAKNYGDPGAP_/100
mpak['PAKNECONOTHRXN'].dekomp(start=2025,end=2029);
Formula        :
 FRML <DAMP,STOC> PAKNECONOTHRXN = (PAKNECONOTHRXN(-1)*EXP(PAKNECONOTHRXN_A+ (0.590372627657176*((LOG(PAKNYGDPFCSTXN))-(LOG(PAKNYGDPFCSTXN(-1))))+((PAKGGREVGNFSXN/100)-(PAKGGREVGNFSXN(-1)/100))+(1-0.590372627657176)*((LOG(PAKNEIMPGNFSXN))-(LOG(PAKNEIMPGNFSXN(-1))))+0.2*PAKNYGDPGAP_/100) )) * (1-PAKNECONOTHRXN_D)+ PAKNECONOTHRXN_X*PAKNECONOTHRXN_D  $ 

                      2025       2026       2027       2028       2029
Variable    lag                                                       
Base        0         2.50       2.65       2.81       2.96       3.11
Alternative 0         2.55       2.71       2.87       3.03       3.19
Difference  0         0.05       0.06       0.07       0.08       0.08
Percent     0         1.95       2.26       2.47       2.61       2.65

 Contributions to difference for  PAKNECONOTHRXN
                           2025       2026       2027       2028       2029
Variable         lag                                                       
PAKNECONOTHRXN   -1       -0.00       0.05       0.06       0.07       0.08
PAKNECONOTHRXN_A  0       -0.00      -0.00      -0.00      -0.00      -0.00
PAKNYGDPFCSTXN    0        0.00       0.01       0.01       0.02       0.02
                 -1       -0.00      -0.00      -0.01      -0.01      -0.02
PAKGGREVGNFSXN    0       -0.00      -0.00      -0.00      -0.00      -0.00
                 -1       -0.00      -0.00      -0.00      -0.00      -0.00
PAKNEIMPGNFSXN    0        0.05       0.05       0.05       0.05       0.05
                 -1       -0.00      -0.05      -0.05      -0.05      -0.05
PAKNYGDPGAP_      0        0.00       0.00       0.00       0.00       0.00
PAKNECONOTHRXN_D  0       -0.00      -0.00      -0.00      -0.00      -0.00
PAKNECONOTHRXN_X  0       -0.00      -0.00      -0.00      -0.00      -0.00

 Share of contributions to difference for  PAKNECONOTHRXN
                           2025       2026       2027       2028       2029
Variable         lag                                                       
PAKNECONOTHRXN   -1         -0%        87%        91%        95%        98%
PAKNEIMPGNFSXN    0         95%        79%        70%        63%        59%
PAKNYGDPFCSTXN    0          1%        12%        18%        22%        25%
PAKNYGDPGAP_      0          4%         6%         4%         3%         1%
PAKNECONOTHRXN_A  0         -0%        -0%        -0%        -0%        -0%
PAKGGREVGNFSXN    0         -0%        -0%        -0%        -0%        -0%
                 -1         -0%        -0%        -0%        -0%        -0%
PAKNECONOTHRXN_D  0         -0%        -0%        -0%        -0%        -0%
PAKNECONOTHRXN_X  0         -0%        -0%        -0%        -0%        -0%
PAKNYGDPFCSTXN   -1         -0%        -1%       -11%       -17%       -22%
PAKNEIMPGNFSXN   -1         -0%       -84%       -74%       -67%       -63%
Total             0        100%        99%        99%        99%        99%
Residual          0          0%        -1%        -1%        -1%        -1%

 Difference in growth rate PAKNECONOTHRXN
                      2025       2026       2027       2028       2029
Variable    lag                                                       
Base        0         6.7%       6.2%       5.8%       5.4%       5.1%
Alternative 0         8.7%       6.5%       6.0%       5.6%       5.2%
Difference  0         2.1%       0.3%       0.2%       0.1%       0.0%
None

 Contribution to growth rate PAKNECONOTHRXN
                           2025       2026       2027       2028       2029
Variable         lag                                                       
PAKNECONOTHRXN   -1        0.0%       2.0%       0.3%       0.2%       0.1%
PAKNECONOTHRXN_A  0        0.0%      -0.0%      -0.0%       0.0%      -0.0%
PAKNYGDPFCSTXN    0        0.0%       0.3%       0.2%       0.1%       0.1%
                 -1        0.0%      -0.0%      -0.3%      -0.2%      -0.1%
PAKGGREVGNFSXN    0        0.0%      -0.0%      -0.0%       0.0%      -0.0%
                 -1        0.0%      -0.0%      -0.0%       0.0%      -0.0%
PAKNEIMPGNFSXN    0        2.0%      -0.1%      -0.1%      -0.1%      -0.1%
                 -1        0.0%      -2.0%       0.1%       0.1%       0.1%
PAKNYGDPGAP_      0        0.1%       0.0%      -0.0%      -0.0%      -0.0%
PAKNECONOTHRXN_D  0        0.0%      -0.0%      -0.0%       0.0%      -0.0%
PAKNECONOTHRXN_X  0        0.0%      -0.0%      -0.0%       0.0%      -0.0%
Total             0        2.1%       0.3%       0.2%       0.1%       0.0%
Residual          0        0.0%      -0.0%      -0.0%      -0.0%      -0.0%

These results indicate that much of the initial impact on prices is coming from the increase in the price of imported goods (which includes a large fuel component). As time progresses, the imported inflation component declines (because fuel and import prices are no longer rising) and the lagged consumption price dominates (the level this period is basically determined by the price level in the previous period) . Other factors such as the cost of domestically produced goods play a larger role and the net impact of imported prices (the total of the contemporaneous and lagged value) approaches zero. Cyclical pressure are initially adding to inflation before declining and eventually turning negative.

2.6. The get_att() method provides more control over the outputs of .dekomp()#

Following a call to the .dekomp() method, the .get_att() method provides a range of mechanisms that allow the results to be displayed in different ways.

2.6.1. The default display of .get_att()#

By default .get_att() displays the share contributions of RHS variables to the total change in the LHS variable. The start= and end= options allow the period for which results are displayed to be restricted.

mpak.PAKNECONPRVTKN.get_att(start=2025,end=2035)
get attribution

2.6.2. Options: Lag=True/False#

Because the decomposition of the equation is based on the normalized (levelized) version of the equation, for equations initially written as growth rates or ECMs many variables will occur several times in the attribution table with both the contribution of the current value of the variable and those of any lagged versions that appear in the normalized equation.

The Lag=False option changes the default behavior of .get_att() and aggregates the contributions of different lags.

By aggregating the lags, the net effect of changes in the variables can be more easily determined. Below it is clearer that the initial impact of higher import prices drove most of the inflation response. In subsequent periods, import prices were stable or even falling so most of the contribution to the change in the level of other goods inflation was from the lagged dependent variable and the changed state of the economic cycle (the Gap variable which initially was adding to inflationary pressures eventually subtracts from inflation as the economy slows).

mpak.PAKNECONOTHRXN.get_att(lag=False,start=2025,end=2035)
Menu to start notebooks in subfolders

2.6.3. Options: Type=”growth/pct/Level”#

The option Type controls which of the tables generated by dekomp() is displayed. The contributions of RHS variables to the level of the dependent variable (=level), the share of the observed change in the RHS variable attributable to each dependent variable (=pct), and the change in the growth rate (=growth)of the LHS available attributable to the changes in the growth rate of each RHS variable.

2.6.4. Options: threshold=xx”#

The threshold= option will suppress from the output those variables whose contribution is less than the stated threshold.

In the example below, lags are suppressed, and only contributions to the growth rate of variables whose largest contribution was more than \(\pm\)0.1 percent are displayed. The dropped variables influence is aggregated and displayed in a row labeled small.

2.6.4.1. Options: bare=True/False#

If bare is set to False then the values of the LHS variable in the basedf and lastdf dataframes and their difference are also displayed. By default this option is True which suppresses the display.

mpak.PAKNECONPRVTKN.get_att(lag=False,type='growth',bare=False,threshold=0.1,start=2020,end=2024)
Menu to start notebooks in subfolders

2.6.5. Several examples#

Here the default type (pct) is displayed and the threshold is set to 10, so only variables whose aggregate impact was more than 10 percent of the total in one or more of the displayed years are shown.

mpak.PAKNECONPRVTKN.get_att(lag=False,threshold=10,start=2025,end=2035)
Menu to start notebooks in subfolders

The three examples below show the impact on real consumption of the changes induced on its LHS variables as changes in percent level and growth, with the threshold set to focus only on the main channels.

mpak.PAKNECONPRVTKN.get_att(lag=False,threshold=10,bare=False,start=2025,end=2029);
mpak.PAKNECONPRVTKN.get_att(lag=False,threshold=10,type='level',bare=False,start=2025,end=2029);
mpak.PAKNECONPRVTKN.get_att(lag=False,threshold=0.1,type='growth',bare=False,start=2025,end=2029);
Menu to start notebooks in subfolders

2.6.6. Displaying .dekomp() results graphically#

The dekomp_plot method allows singe-equation decompositions to be displayed graphically. Below in the initial periods, the import price, and cost-push factors dominate, but as the model equilibrates the lagged level of the price deflator explains virtually all of the movement in the level of the price.

fig=mpak.dekomp_plot('PAKNECONOTHRXN',pct=True,rename=True,threshold=.01,lag=False); #decomp of the change in the level
../../_images/b761a2f84f61b75dfaf1b03c5d76a90736e3f9aa365907b43e8f4edee1b962c7.png

In the following example the change in the level of the dependent variable is displayed for a restricted time period. Here the distinction between the initial impulse (import prices) and the lagged effect of past prices is very evident.

with mpak.set_smpl(2020,2030):
    fig=mpak.dekomp_plot('PAKNECONOTHRXN',pct=False,rename=True,threshold=.005,lag=False); #decomp of the change in the level
../../_images/9997cb89025488a18533a3c9ef88d4c77a99988687f193f04489017895beb744.png

2.6.7. the time_att option#

The above displays focused on the difference between the values in the two dataframes basedf and lastdf.

By setting he time_att option to True, get_att() displays the contribution of changes in the levels of the RHS variables between t and t-1,in explaining the changes in the LHS variable between t and t-1 with all data pulled from the same .lastdf datafame.

Note

With the time_att option set only the .lastdf dataframe is used. The comparison is not .basedf vs .lastdf but the influence of last year’s changes on the level of this year’s variable. The attribution is calculated by lagging each right hand side variable one year and recalculating the equation.

mpak.PAKCCEMISCO2TKN .get_att(time_att= True,type='level',bare=0);
  2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100
Level/level                                                                                                                                                        
Difference -46,497,333.26 6,361,991.64 6,744,054.82 6,980,146.40 7,236,797.63 7,475,683.84 7,709,083.40 7,921,379.24 8,105,198.06 8,264,551.03 8,411,113.13 8,557,989.57 8,716,014.59 8,892,517.32 9,091,519.56 9,314,669.25 9,562,201.24 9,833,593.71 10,127,953.98 10,444,143.56 10,780,854.57 11,136,675.78 11,510,179.34 11,900,016.28 12,305,001.25 12,724,167.84 13,156,789.43 13,602,373.28 14,060,640.69 14,531,460.73 15,014,874.72 15,511,016.97 16,020,101.91 16,542,438.31 17,078,367.42 17,628,279.23 18,192,591.71 18,771,754.63 19,366,234.07 19,976,507.93 20,603,063.35 21,246,393.31 21,906,992.54 22,585,368.28 23,282,030.96 23,997,497.87 24,732,304.46 25,486,988.96 26,262,106.23 27,058,226.95 27,875,941.37 28,715,856.57 29,578,600.81 30,464,831.16 31,375,202.58 32,310,419.20 33,271,205.58 34,258,306.70 35,272,493.67 36,314,563.05 37,385,340.00 38,485,676.15 39,616,452.10 40,778,576.40 41,972,987.97 43,200,649.10 44,462,559.73 45,759,747.74 47,093,272.95 48,464,224.76 49,873,727.16 51,322,937.41 52,813,049.10 54,345,287.94 55,920,922.35 57,541,243.17
Percent -20.18 3.46 3.55 3.54 3.55 3.54 3.53 3.50 3.46 3.41 3.36 3.30 3.26 3.22 3.19 3.16 3.15 3.14 3.14 3.13 3.14 3.14 3.15 3.16 3.16 3.17 3.18 3.18 3.19 3.20 3.20 3.20 3.20 3.21 3.21 3.21 3.21 3.21 3.21 3.20 3.20 3.20 3.20 3.19 3.19 3.19 3.18 3.18 3.17 3.17 3.17 3.16 3.16 3.15 3.15 3.14 3.14 3.13 3.13 3.12 3.12 3.11 3.10 3.10 3.09 3.09 3.08 3.08 3.07 3.07 3.06 3.06 3.06 3.05 3.05 3.04
t 183,872,963.10 190,234,954.74 196,979,009.56 203,959,155.97 211,195,953.60 218,671,637.43 226,380,720.83 234,302,100.08 242,407,298.14 250,671,849.17 259,082,962.30 267,640,951.87 276,356,966.46 285,249,483.78 294,341,003.34 303,655,672.59 313,217,873.83 323,051,467.54 333,179,421.52 343,623,565.08 354,404,419.64 365,541,095.42 377,051,274.76 388,951,291.04 401,256,292.29 413,980,460.13 427,137,249.56 440,739,622.85 454,800,263.53 469,331,724.27 484,346,598.99 499,857,615.96 515,877,717.87 532,420,156.18 549,498,523.60 567,126,802.83 585,319,394.54 604,091,149.17 623,457,383.24 643,433,891.17 664,036,954.52 685,283,347.83 707,190,340.37 729,775,708.65 753,057,739.61 777,055,237.48 801,787,541.94 827,274,530.91 853,536,637.14 880,594,864.09 908,470,805.46 937,186,662.03 966,765,262.83 997,230,093.99 1,028,605,296.57 1,060,915,715.77 1,094,186,921.35 1,128,445,228.05 1,163,717,721.72 1,200,032,284.78 1,237,417,624.77 1,275,903,300.92 1,315,519,753.02 1,356,298,329.43 1,398,271,317.39 1,441,471,966.50 1,485,934,526.23 1,531,694,273.97 1,578,787,546.92 1,627,251,771.69 1,677,125,498.85 1,728,448,436.26 1,781,261,485.35 1,835,606,773.29 1,891,527,695.64 1,949,068,938.81
t-1 230,370,296.36 183,872,963.10 190,234,954.74 196,979,009.56 203,959,155.97 211,195,953.60 218,671,637.43 226,380,720.83 234,302,100.08 242,407,298.14 250,671,849.17 259,082,962.30 267,640,951.87 276,356,966.46 285,249,483.78 294,341,003.34 303,655,672.59 313,217,873.83 323,051,467.54 333,179,421.52 343,623,565.08 354,404,419.64 365,541,095.42 377,051,274.76 388,951,291.04 401,256,292.29 413,980,460.13 427,137,249.56 440,739,622.85 454,800,263.53 469,331,724.27 484,346,598.99 499,857,615.96 515,877,717.87 532,420,156.18 549,498,523.60 567,126,802.83 585,319,394.54 604,091,149.17 623,457,383.24 643,433,891.17 664,036,954.52 685,283,347.83 707,190,340.37 729,775,708.65 753,057,739.61 777,055,237.48 801,787,541.94 827,274,530.91 853,536,637.14 880,594,864.09 908,470,805.46 937,186,662.03 966,765,262.83 997,230,093.99 1,028,605,296.57 1,060,915,715.77 1,094,186,921.35 1,128,445,228.05 1,163,717,721.72 1,200,032,284.78 1,237,417,624.77 1,275,903,300.92 1,315,519,753.02 1,356,298,329.43 1,398,271,317.39 1,441,471,966.50 1,485,934,526.23 1,531,694,273.97 1,578,787,546.92 1,627,251,771.69 1,677,125,498.85 1,728,448,436.26 1,781,261,485.35 1,835,606,773.29 1,891,527,695.64
PAKCCEMISCO2CKN -21,415,362.19 1,495,858.03 1,573,495.56 1,627,368.51 1,683,809.32 1,734,875.82 1,784,392.96 1,830,061.66 1,870,807.68 1,907,515.42 1,942,464.91 1,978,191.73 2,016,795.67 2,059,697.72 2,107,665.66 2,160,987.72 2,219,658.88 2,283,512.64 2,352,302.68 2,425,732.45 2,503,474.59 2,585,187.21 2,670,533.40 2,759,201.89 2,850,924.85 2,945,489.20 3,042,740.30 3,142,579.72 3,244,959.95 3,349,868.74 3,457,333.45 3,567,402.49 3,680,141.75 3,795,636.97 3,913,979.61 4,035,270.01 4,159,612.67 4,287,117.02 4,417,894.05 4,552,055.41 4,689,713.05 4,830,978.64 4,975,962.83 5,124,777.91 5,277,535.89 5,434,349.50 5,595,334.92 5,760,608.43 5,930,289.59 6,104,501.20 6,283,370.16 6,467,026.86 6,655,606.27 6,849,249.60 7,048,097.29 7,252,300.67 7,462,015.31 7,677,401.15 7,898,623.71 8,125,853.86 8,359,268.59 8,599,050.44 8,845,388.10 9,098,476.12 9,358,515.46 9,625,711.85 9,900,279.09 10,182,436.78 10,472,411.17 10,770,434.71 11,076,747.10 11,391,595.01 11,715,232.68 12,047,921.05 12,389,930.16 12,741,534.31
PAKCCEMISCO2OKN -9,501,227.66 3,259,546.29 3,441,946.76 3,546,118.72 3,659,125.19 3,756,681.24 3,850,837.49 3,934,840.62 4,005,973.42 4,067,384.08 4,126,058.42 4,189,337.41 4,262,965.79 4,350,529.70 4,453,667.94 4,572,664.89 4,707,031.58 4,855,898.77 5,018,249.18 5,192,997.27 5,379,037.46 5,575,281.56 5,780,703.75 5,994,386.75 6,215,559.91 6,443,619.83 6,678,132.01 6,918,818.20 7,165,537.44 7,418,242.30 7,676,987.17 7,941,879.53 8,213,070.06 8,490,757.92 8,775,155.14 9,066,494.66 9,365,018.54 9,670,980.11 9,984,635.77 10,306,243.01 10,636,059.68 10,974,342.74 11,321,346.61 11,677,329.77 12,042,550.06 12,417,267.29 12,801,749.72 13,196,266.02 13,601,093.02 14,016,515.44 14,442,828.02 14,880,334.08 15,329,347.94 15,790,199.05 16,263,215.09 16,748,749.84 17,247,167.33 17,758,842.02 18,284,161.75 18,823,527.19 19,377,353.64 19,946,069.68 20,530,118.49 21,129,957.27 21,746,058.54 22,378,906.17 23,029,003.21 23,696,866.53 24,383,028.84 25,088,037.55 25,812,457.31 26,556,869.33 27,321,872.81 28,108,082.83 28,916,135.96 29,746,679.09
PAKCCEMISCO2GKN -15,580,743.41 1,606,587.32 1,728,612.51 1,806,659.17 1,893,863.12 1,984,126.78 2,073,852.95 2,156,476.96 2,228,416.96 2,289,651.53 2,342,589.81 2,390,460.44 2,436,253.13 2,482,289.91 2,530,185.97 2,581,016.64 2,635,510.78 2,694,182.30 2,757,402.12 2,825,413.83 2,898,342.51 2,976,207.01 3,058,942.19 3,146,427.64 3,238,516.49 3,335,058.80 3,435,917.13 3,540,975.37 3,650,143.30 3,763,349.69 3,880,554.10 4,001,734.96 4,126,890.11 4,256,043.41 4,389,232.68 4,526,514.56 4,667,960.50 4,813,657.50 4,963,704.26 5,118,209.51 5,277,290.62 5,441,071.94 5,609,683.10 5,783,260.60 5,961,945.01 6,145,881.09 6,335,219.81 6,530,114.51 6,730,723.61 6,937,210.31 7,149,743.20 7,368,495.63 7,593,646.60 7,825,382.51 8,063,890.20 8,309,368.69 8,562,022.94 8,822,063.53 9,089,708.22 9,365,182.01 9,648,717.77 9,940,556.03 10,240,945.51 10,550,143.02 10,868,413.97 11,196,031.08 11,533,277.44 11,880,444.43 12,237,832.95 12,605,752.51 12,984,522.74 13,374,473.07 13,775,943.61 14,189,284.06 14,614,856.24 15,053,029.77
Menu to start notebooks in subfolders
help(mpak.get_att)
Help on method get_att in module modelclass:

get_att(n, type='pct', filter=False, lag=True, start='', end='', time_att=False, threshold=0.0) method of modelclass.model instance
    Calculate the attribution percentage for a variable.

    Parameters:
        n (str): Name of the variable to calculate attribution for.
        type (str): Type of attribution calculation. Options: 'pct' (percentage), 'level', 'growth'. Default: 'pct'.
        filter (bool): [Deprecated] Use threshold instead of filter. Default: False.
        lag (bool): Flag to indicate whether to include lag information in the output. Default: True.
        start (str): Start period for calculation. If not provided, uses the first period in the model instance. Default: ''.
        end (str): End period for calculation. If not provided, uses the last period in the model instance. Default: ''.
        time_att (bool): Flag to indicate time attribute calculation. Default: False.
        threshold (float): Threshold value for excluding rows with values close to zero. Default: 0.0.

    Returns:
        pandas.DataFrame: DataFrame containing the calculated attribution results.

    Raises:
        Exception: If an invalid type is provided.
help(mpak.dekomp_plot)
Help on method dekomp_plot in module modelclass:

dekomp_plot(varnavn, sort=True, pct=True, per='', top=0.9, threshold=0.0, lag=True, rename=True, nametrans=<function Dekomp_Mixin.<lambda> at 0x00000167FD9472E0>, time_att=False) method of modelclass.model instance
    Returns  a chart with attribution for a variable over the smpl

    Parameters
    ----------
    varnavn : TYPE
        variable name.
    sort : TYPE, optional
        . The default is False.
    pct : TYPE, optional
        display pct contribution . The default is True.
    per : TYPE, optional
        DESCRIPTION. The default is ''.
    threshold : TYPE, optional
        cutoff. The default is 0.0.
    rename : TYPE, optional
        Use descriptions instead of variable names. The default is True.
    time_att : TYPE, optional
        Do time attribution . The default is False.
    lag : TYPE, optional
       separete by lags The default is True.
    top : TYPE, optional
      where to place the title


    Returns
    -------
    a matplotlib figure instance .

2.7. Trace and decomposition combined#

The .tracepre() method can combine the graphical representation of the tracepre() method described in the previous chapter and the tabular results from dekomp().

This is implicit in the standard call to .tracepre()where the thickness of the lines is derived from the empirical importance of the changes in each LHS variable in determining the change in the RHS variable.

mpak.PAKNECONPRVTKN.tracepre(png=latex,size=(2,4));
../../_images/e6feb13f43f49b56ea48a55b006119d233f125bbd18783cd86d03b9ab355b414.png

2.8. Tabular output from tracepre()#

The results for .tracepre can be displayed in a number of ways and the results can be saved as pictures.

up = xx

determines how many levels of parents to include

showdata|sd=True

Causes the tables of attribution for each displayed variable to be displayed

showdata|sd=<’pattern of variable names’>

will include a table of values for each variable matching the pattern (including wildcharts

attshow|ats = True

adds in the contribution of each to the total change

growthshow|gs = True

will include a table of growth for each variable

HR = True

will reorient the dependency graph

filter=<xx>

restrict outputs to variables that explain at least xx% of the change in the level of dependent variable

browser = True

Opens a browser with the resulting dependency graph - useful for zooming on a big graph or table

pgn = True

will display as a png picture

svg = True

will display as a svg picture which can be zoomed

pdf = True

will display as a pdf picture

eps = True

will create a eps file (a latex format)

saveas = <a file name without extension>

will save the picture wit the filename with an added extension reflection the picture type

with mpak.set_smpl(2020,2030):
    mpak.PAKNECONOTHRXN.tracepre(filter=5.0,HR=False,showdata= True,attshow=True,per=2020,png=latex)
../../_images/bb792fbc57e206c89cbd38598b000d6beae41be76edb8d8b219fbe4a70d2e42d.png

The big difference with this representation is the contributions of both the direct that directly impact the LHS variable (as well as the influence of those variables one or two steps up the causal chain) can be traced.

Below the same command as above but we specify that we want to go up two levels in the causal chain.

with mpak.set_smpl(2020,2030):
    mpak.PAKNECONOTHRXN.tracepre(up=2,filter=5,HR=False,sd= True,ats=True,png=latex)
../../_images/d8eec046030b789f59e567e2632c6f46e28de065ff1a446a2adc7a104a1e769e.png
with mpak.set_smpl(2020,2023):
    mpak.PAKNECONPRVTKN.tracepre(sd='*lcn',filter=10,HR=1,ats=1,up=2
    ,growthshow=1,png=latex)
No graph PAKNECONPRVTKN
The graph is empty
Perhaps filter prunes to much

As indicated by the error message the filter is too fine, and has eliminated all variables from the output. Below the same command without the filter option.

with mpak.set_smpl(2020,2023):
    mpak.PAKNECONPRVTKN.tracepre(sd='*lcn',HR=1,ats=1,up=2
    ,growthshow=1,png=latex)
../../_images/26ef44f74269099cbe224df3d7fca0f68c5beea6ac8a23964635e2face917520.png

2.9. Chart of the contributions over time#

with mpak.set_smpl(2020,2030):
    mpak.dekomp_plot('PAKNYGDPFCSTXN',threshold=5);  # gives a waterfall of contributions
../../_images/94a65c9e2a1a92bc274d7cfc3c5427a87b3608bba56e62325b8a7aa6923701b1.png

2.10. Chart of the contributions for one year#

It can be useful to visualize the attribution as a waterfall chart for a single year

mpak.dekomp_plot_per('PAKNYGDPFCSTXN',per=2027,threshold=5)  # gives a waterfall of contributions
../../_images/9fa7fbb3e80f545f43610bbd66861d677365c2d52134efc73c06e93e15a65bc1.png
mpak.dekomp_plot_per('PAKNYGDPFCSTXN',per=2027,threshold=5)  # gives a waterfall of contributions
../../_images/9fa7fbb3e80f545f43610bbd66861d677365c2d52134efc73c06e93e15a65bc1.png

2.11. Sorted waterfall of contributions#

mpak.dekomp_plot_per('PAKNYGDPFCSTXN',per=2029,threshold=5,sort=True)  # gives a waterfall of contributions
../../_images/b6efad185a1bc7ae542ae3c48249dbe9a0aaa10588c11b05ddd24011c8ca6b2c.png

2.12. Impacts at the model level: the .totdif() method#

The method .totdif() returns an instance of the totdif class, which provides a number of methods and properties to explore decomposition at the model level.

It works by solving the model numerous times, each time changing one of the right hand side variables and calculating the impact on all dependent variables. By default it uses the values from the .lastdf DataFrame as the shock values and the values in .basedf as the initial values. Separate simulations are run for every exogenous (or exogenized) variables that have changed between the two DataFrames.

For advanced users the RHS variables can be grouped into user defined blocks, which in cases where there are many changes can help identify the main causal pathways.

2.12.1. The .exo_dif() method#

The .exodif() method displays only the exogenous variables that have changed between the two DataFrames (the shock). Exogenous variables whose results have not changed are omitted. It determines which of the exogenous variables have changed between .lastdfand .basedf and then returns a DataFrame with the changes in the values.

In this case the DataFrame contains the effect of updating the \(CO^2\) tax to 30 for coal, gas and oil. .exo_dif() is automatically called by the .totdif() method but can also be called directly b y the user.

mpak.exodif()
PAKGGREVCO2CER PAKGGREVCO2GER PAKGGREVCO2OER
2020 35.55 71.0 38.71
2021 35.55 71.0 38.71
2022 35.55 71.0 38.71
2023 35.55 71.0 38.71
2024 35.55 71.0 38.71
... ... ... ...
2096 35.55 71.0 38.71
2097 35.55 71.0 38.71
2098 35.55 71.0 38.71
2099 35.55 71.0 38.71
2100 35.55 71.0 38.71

81 rows × 3 columns

2.12.2. The .totdif() command calculates the contribution of each changed variable to the changes in a specified LHS variable#

This involves solving the model a number of times, so can take some time. How long it takes to execute will depend on the computer, the model and the number of changes made. In this instance the .totaldif takes between 2 and 5 seconds depending on computer.

totdekomp = mpak.totdif() # Calculate the total derivative½s of all equations in the model.
Total dekomp took       :         6.308 Seconds

2.12.3. The method .explain_all() presents the results graphically#

In the example below, the relative importance of the three shocked carbon taxes on the change in real GDP are presented.

showvar = 'PAKNYGDPMKTPKN'
totdekomp.explain_all(showvar,kind='area',use='growth',stacked=True,
                      title="Contributions of different carbon taxes to Real GDP growth") ;
../../_images/d8d852668ac58535f4ab0d0b36c686b94992364b9a189ff6fc9c608ebbca7adc.png
help(totdekomp.explain_all)
Help on method explain_all in module modeldekom:

explain_all(pat='', stacked=True, kind='bar', top=0.9, title='', use='level', threshold=0.0, resample='', axvline=None) method of modeldekom.totdif instance
    Explains all

    Args:
        pat (TYPE, optional): DESCRIPTION. Defaults to ''.
        stacked (TYPE, optional): DESCRIPTION. Defaults to True.
        kind (TYPE, optional): DESCRIPTION. Defaults to 'bar'.
        top (TYPE, optional): DESCRIPTION. Defaults to 0.9.
        title (TYPE, optional): DESCRIPTION. Defaults to ''.
        use (TYPE, optional): DESCRIPTION. Defaults to 'level'.
        threshold (TYPE, optional): DESCRIPTION. Defaults to 0.0.
        resample (TYPE, optional): DESCRIPTION. Defaults to ''.
        axvline (TYPE, optional): DESCRIPTION. Defaults to None.

    Returns:
        None.

2.12.4. Many variables#

If many variables are passed to explain_all then separate graphs will be created for each.

showvar = 'PAKNYGDPMKTPKN PAKCCEMISCO2CKN PAKCCEMISCO2OKN PAKCCEMISCO2GKN PAKGGREVTOTLCN'

totdekomp.explain_all(showvar,kind='area',stacked=True,title="Contributions of different carbon taxes to Real GDP,growth") ;
../../_images/f6339051565dae5e6d63e266a5e2d3b55a870be7658e78e4615c33058eb19587.png

2.12.5. Similarly the impacts on different variables for one year can be shown#

showvar = 'PAKNYGDPMKTPKN PAKNECONPRVTXN'

totdekomp.explain_per(showvar,per=2028,ysize=8,title='Decomposition, level=2023')
../../_images/18cd0d4e5c5cd661ca6ffb471333de5cb11d9758b406ee57643b799126108be9.png

2.12.6. Or an interactive widgets can be generated#

This allows the user to select the specific variable of interest and what to display:

Note

If this is read in a manual the widget is not live.

In a notebook the selection widgets are live.

mpak.get_att_gui(var='PAKGGREVTOTLCN',ysize=7)
Menu to start notebooks in subfolders

2.12.7. Decomposition of the last year#

showvar = 'PAKNYGDPMKTPKN'
totdekomp.explain_last(showvar,ysize=8,title='Decomposition last period, level')
../../_images/ef4c506274312a4bf9a3b8768e85022adb9d2eb259cc14ee4c0bcacae8c61537.png

2.12.8. Decomposition of accumulated effects#

totdekomp.explain_sum(showvar,ysize=8,title="Decomposition, sum over all periods,level")
../../_images/3ce0fb9226eb51c3379a6f6da145f1ff9e462f9df54a1de4c42c7be7d5ffb787.png

2.13. More advanced model attribution#

For some simulations the number of changed exogenous variables can be large. Using a dictionary to contain the experiments allows us to manage multiple scenarios and multiple outputs.

Using this approach, if there are many simulations, data can be filtered in order to look only at the variables with an impact above a certain threshold.

2.13.1. Grouping variables#

If many exogenous variables were shocked, exploring impacts may be made easier by aggregating the impacts of some groups or sub-groups of variables. Grouping variables allows the user to explore the results in a more flexible way slicing and dicing the impact along different dimensions.

In the example below, the impacts of changing the carbon tax on gas and oil tax are grouped together (aggregated) and the impact of the coal tax is displayed separately.

shocks = {'gas and Oil':['PAKGGREVCO2OER', 'PAKGGREVCO2GER'],'Coal':['PAKGGREVCO2CER']}
totdekomp_group = mpak.totdif(experiments = shocks) # Calculate the total derivative½s of all equations in the model.
Total dekomp took       :         3.748 Seconds
showvar = 'PAKNYGDPMKTPKN'
totdekomp_group.explain_all(showvar,kind='area',stacked=True,title='GDP impact of coal and non-coal carbon taxes');    
../../_images/1ccdfb4b449ce601f203ed05b6476c30c96a4eb782ef524498526c869a0be284.png

While this is a fairly simple example, the grouping mechanism allows us to focus our attention on one factor (the coal price in this instance).

Here, even though the coal tax was increased by the most (in the baseline it was subsidized), it had a relatively small share in total energy production, so its GDP impact was relatively small.

2.13.2. Single equation attribution chart#

The results can be visualized in different ways.

mpak.dekomp_plot_per('PAKNYGDPMKTPKN',
                     per=2025,           # Period to be displayed
                     pct=False,          # Do not show differences as percent changes
                     rename=True,        # Use the long-form vs mnemonic description of variable
                     sort=True,          # 
                     threshold =200000,
                     ysize=7            # Size of y axis in inches   
                     )
../../_images/45ae9709949c3b868eef652e01eda52b1ced48af92d18ba397de09d491c832e0.png

2.13.3. Decomposition of changes over time#

A classic query is to understand what is driving changes over time. The time_att=True option quantifies the impact of changes over time in the LHS variables on changes in the dependent variable over time using data from the lastdf DataFrame.

with mpak.set_smpl(2020,2024):
    mpak['PAKNYGDPMKTPKN'].dekomp(time_att=True)
Formula        : FRML <IDENT> PAKNYGDPMKTPKN = PAKNECONPRVTKN+PAKNECONGOVTKN+PAKNEGDIFTOTKN+PAKNEGDISTKBKN+PAKNEEXPGNFSKN-PAKNEIMPGNFSKN+PAKNYGDPDISCKN+PAKADAP*PAKDISPREPKN $ 

                      2020        2021        2022        2023        2024
Variable   lag                                                            
t-1        0   25760579.37 26273942.22 26511370.46 26685141.91 26963077.59
t          0   26273942.22 26511370.46 26685141.91 26963077.59 27393200.45
Difference 0     513362.86   237428.23   173771.45   277935.69   430122.85
Percent    0          1.99        0.90        0.66        1.04        1.60

 Contributions to difference for  PAKNYGDPMKTPKN
                         2020       2021       2022       2023       2024
Variable       lag                                                       
PAKNECONPRVTKN 0    654250.10  299926.97  191312.65  263735.02  390661.47
PAKNECONGOVTKN 0     67306.62   30293.58   26781.38   52462.03   84392.13
PAKNEGDIFTOTKN 0     60338.01   36679.60   21435.92   19393.71   24600.23
PAKNEGDISTKBKN 0      9896.77   10138.33   10385.78   10639.27   10898.95
PAKNEEXPGNFSKN 0     96445.77  110587.72  118464.57  122733.42  124943.57
PAKNEIMPGNFSKN 0   -376170.79 -251525.99 -195969.30 -192421.42 -206801.16
PAKNYGDPDISCKN 0      1296.39    1328.03    1360.45    1393.65    1427.67
PAKADAP        0        -0.00      -0.00      -0.00      -0.00      -0.00
PAKDISPREPKN   0        -0.00      -0.00      -0.00      -0.00      -0.00

 Share of contributions to difference for  PAKNYGDPMKTPKN
                         2020       2021       2022       2023       2024
Variable       lag                                                       
PAKNECONPRVTKN 0         127%       126%       110%        95%        91%
PAKNEEXPGNFSKN 0          19%        47%        68%        44%        29%
PAKNECONGOVTKN 0          13%        13%        15%        19%        20%
PAKNEGDIFTOTKN 0          12%        15%        12%         7%         6%
PAKNEGDISTKBKN 0           2%         4%         6%         4%         3%
PAKNYGDPDISCKN 0           0%         1%         1%         1%         0%
PAKADAP        0          -0%        -0%        -0%        -0%        -0%
PAKDISPREPKN   0          -0%        -0%        -0%        -0%        -0%
PAKNEIMPGNFSKN 0         -73%      -106%      -113%       -69%       -48%
Total          0         100%       100%       100%       100%       100%
Residual       0          -0%        -0%        -0%        -0%        -0%

 Difference in growth rate PAKNYGDPMKTPKN
                     2020       2021       2022       2023       2024
Variable   lag                                                       
t-1        0         4.7%       2.0%       0.9%       0.7%       1.0%
t          0         2.0%       0.9%       0.7%       1.0%       1.6%
Difference 0        -2.7%      -1.1%      -0.2%       0.4%       0.6%
None

 Contribution to growth rate PAKNYGDPMKTPKN
                         2020       2021       2022       2023       2024
Variable       lag                                                       
PAKNECONPRVTKN 0        -3.4%      -1.4%      -0.4%       0.3%       0.5%
PAKNECONGOVTKN 0        -0.3%      -0.1%      -0.0%       0.1%       0.1%
PAKNEGDIFTOTKN 0        -0.1%      -0.1%      -0.1%      -0.0%       0.0%
PAKNEGDISTKBKN 0         0.0%       0.0%       0.0%       0.0%       0.0%
PAKNEEXPGNFSKN 0         0.1%       0.1%       0.0%       0.0%       0.0%
PAKNEIMPGNFSKN 0         0.9%       0.5%       0.2%       0.0%      -0.0%
PAKNYGDPDISCKN 0         0.0%       0.0%       0.0%       0.0%       0.0%
PAKADAP        0         0.0%       0.0%      -0.0%       0.0%      -0.0%
PAKDISPREPKN   0         0.0%       0.0%      -0.0%       0.0%      -0.0%
Total          0        -2.8%      -1.1%      -0.3%       0.4%       0.6%
Residual       0        -0.1%      -0.0%      -0.0%      -0.0%      -0.0%
mpak.dekomp_plot('PAKNYGDPMKTPKN',pct=0,rename=1,sort=1,threshold =0,time_att = True);
../../_images/5e06eefb0e92fee63b3b8dd311cf50bac7076c386a67da65e58aa5971ae6412a.png