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
DataFramestored in thepcimfile to establish a baseline.Creates a
DataFramethat is a copy (from 2020) of the active solution inmpakand 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:
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()\):
and calculates \(\Omega_a\) and \(\Omega_b\) as:
And:
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 |
|
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 |
|
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)
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)
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)
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)
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);
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
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
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 |
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));
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)
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)
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)
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
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
mpak.dekomp_plot_per('PAKNYGDPFCSTXN',per=2027,threshold=5) # gives a waterfall of contributions
2.11. Sorted waterfall of contributions#
mpak.dekomp_plot_per('PAKNYGDPFCSTXN',per=2029,threshold=5,sort=True) # gives a waterfall of contributions
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") ;
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") ;
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')
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)
2.12.7. Decomposition of the last year#
showvar = 'PAKNYGDPMKTPKN'
totdekomp.explain_last(showvar,ysize=8,title='Decomposition last period, level')
2.12.8. Decomposition of accumulated effects#
totdekomp.explain_sum(showvar,ysize=8,title="Decomposition, sum over all periods,level")
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');
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
)
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);