Help for locproj

Description

locproj estimates linear and non-linear Impulse Response Functions (IRF) based on the local projections methodology first proposed by Jordà (2005).
The procedure allows easily implementation of several options used in the growing literature of local projections.

It generates temporary variables with the necessary transformations of the response variable in order to estimate the IRF
in the desired transformation option, such as levels, logs, differences, log-differences, cumulative changes or cumulative log-differences.
For every option, the procedure also generates temporary variables with the corresponding transformation of the dependent variable
needed in case the user wants to include lags of the dependent variable that are consistent with the chosen transformation.

locproj allows the user to choose different estimation methods for both time series and panel data, including some instrumental variables methods
currently available in Stata such as ivregress or xtivreg.

locproj reports the IRF, together with its standard error and confidence interval, as an output matrix and through an IRF graph.
The user can easily choose different options for the desired IRF graph, as well as other options to save and use the results.

The options allow defining the desired specification in a fully automatic or in a more explicit way, with many alternatives in between.

If the user chooses the automatic specification, the syntax is very close to a typical regression command in Stata,
with the only restriction that locproj interprets the variable that corresponds to the shock (impulse) as the one just after
the dependent variable or its lagged terms, and only that one variable represents the shock.

Alternatively, the user can choose to explicitly define the shock variable (or variables), the number of lags of the shock, the number of lags
of the dependent variable, and the control variables. As mentioned before, the user can play with alternatives between the
fully automatic or the fully explicit, depending on which option is easier or more convenient to use.

The explicit option is recommended when the shock should include more than one variable, for instance, an additional non-linear term,
or an interaction with another variable.

locproj uses the Stata command lincom to estimate the response to the shock variable or variables, allowing to estimate responses to linear
combinations of variables, including interactions with factor or continuous variables. Importantly, it also allows the use of marginal effects instead of
regression coefficients, which is highly convenient when the response variable is binary and the user wants to estimate the response as a probability.
In the latter case, locproj makes use of the Stata command margins, which could further facilitate the estimation of responses when
the shock corresponds to an interaction of variables (factor or continuous) instead of just a single variable.

locproj also allows different options regarding the horizon and the response starting period. For instance, it automatically adjusts
the horizon in the case that the shock variable(s) is included with a lag and no contemporaneous term, e.g. L.shockvar, in which case
the response at hor = 0 would be equal to 0 and an extra period will be added to final horizon period.

Remark: If the shock includes an interaction with a categorical variable, then we must use one of the options
lcs() or margins().

Syntax

Automatic Specification (Shock and Lags)

locproj
depvar
shock
[depvar lagged-terms]
[shock lagged-terms]
[controls]
[if] [in]
,
[ hor(numlist integer) lcs(string) lcopt(string) fcontrols(varlist) instr(string) transf(string)
met(string) model_options hopt(string) conf(numlist integer) noisily stats saveirf irfname(string)
fact(real) margins mrfvar(varlist) mrpredict(string) mropt(string) nograph title(string)
label(string) zero lcolor(string) ttitle(string) grname(string) grsave(string)
as(string) gropt(string) ]

Explicit Specification (Shock and Lags)

locproj
depvar
[if] [in]
,
[ hor(numlist integer) shock(varlist) controls(varlist) ylags(integer) slags(integer) lcs(string)
lcopt(string) fcontrols(varlist) instr(string) transf(string) met(string) model_options hopt(string)
conf(numlist integer) noisily stats saveirf irfname(string) fact(real) margins mrfvar(varlist)
mrpredict(string) mropt(string) nograph title(string) label(string) zero lcolor(string)
ttitle(string) grname(string) grsave(string) as(string) gropt(string) ]

See help lpgraph for using the post-estimation command lpgraph that allows plotting together results of different estimations.

Options

Model Specification:

hor(numlist/integer) Specifies the number of steps or horizon length for the IRF.
It can be specified either as a range (e.g. hor(0/6) or hor(1/6)), or just as the final horizon period (e.g. hor(6))
in which case the command assumes the horizon starts at period 0 and ends in period 6. The default horizon range is hor = 0,...,5
if nothing is specified.

shock(varlist) Allows to explicitly define the variable or variables that represent the shock or impulse that
will generate the response and the IRF. If this option is not specified the command will automatically choose the first variable that
is inmmediately after the depvar and its lagged terms if they are included in the main varlist.
This option should be used when the desired shock includes more than one variable, for instance a non-linear term or
an interaction term.

lcs(string) Specifies an expression, usually an addition of variables, that defines a linear combination of variables that represents
the desired impulse (shock). This option should be used when the desired shock includes more than one variable and the name of one of them
is not explictily included in the syntax variable list, for instance the constant term (_cons), or the expansion of an expression that
includes factor variable terms, e.g. 12.code#c.xvar. The expression that should go inside the parenthesis is analogous to any expression
that is tested using the commands lincom or test.

slags(integer) Specifies explicitly the number of lags of the shock variable or variables that should be included in the specification.
The lagged terms of the shock could also be included directly in the main varlist next to the first variable that represents the shock.
If more than one variable is specified through the option shock() then the specification will include lags of all of them.

ylags(integer) Specifies explicitly the number of lags of the depvar that should be included in the specification.
The way the lags of the dependent variable are included changes depending on the type of tranformation that is defined by the user
through the option transf().

controls(varlist) Allows to explicitly define the variable or variables that represent the control variables.
If this option is not specified the command simply includes all the variables that are inmmediately after the shock variable(s)
and its lagged terms if they are included in the main varlist.
The control variables could include any number of lags, interactions, or any other desired transformations.

fcontrols(varlist) Specifies any control variable(s) that should be included at the same horizon as the IRF,
i.e. that their forecast should be included depending on the horizon, i.e. fcontrol(t+h) with h = 0...hor.

lcopt(string) Specifies any option available in the command lincom. See lincom for specific help about
the command lincom

Marginal Effect Options:

margins Specifies that the marginal effect of the shock variable is used instead of the regression coefficients.
For simplicity, it only allows using the dydx option of the command margins. See margins for specific help about
the command margins

mrfvar(varlist) Specifies the factor or continuous variable that it is interacted with the shock variable in the specification.
This option should be used together with the shock(varlist) option and the margins option.

mrpred(string) Specifies the option to be used with the predict command to produce the variable that will be used as the response
when using the margins option, e.g. pr, pc1, pu0, xb. It this option is not specified it uses the default option of the estimation method being used.

mropt(string) Allows to specify other options available in the command margins that have not been specified in the previous marginal effect options.
See margins for specific help about using the command margins.

Transformation Options:

transf(string) Specifies the type of transformation that should be applied to the dependent variable when generating the forecasts that are used for each
horizon of the local projection. The available transformations available are the ones in the following list, and they should be written exactly as they are shown:

1. (level): Levels: It keeps the dependent variable as originally specified and uses its forecast h periods ahead
for each horizon of the IRF, i.e. y(t+h) with h = 0...hor. It is the default option in case no transformation is specified.
When the option ylags() is specified, it includes lags of the variable in levels, i.e. y(t-l) with l = 1,...,ylags.

2. (diff): Differences: It uses forecasts of the dependent variable in simple "differences", i.e. y(t+h) - y(t+h-1)
with h = 0...hor. When the option ylags() is specified, it includes lags of the variable in differences, i.e. y(t)-y(t-l)
with l = 1,...,ylags.

3. (cmlt): Cumulative differences: It uses forecasts of the dependent varible in cumulative differences,
i.e. y(t+h) - y(t-1) with h = 0...hor. When the option ylags() is specified, it includes lags of the variable
in differences, i.e. y(t)-y(t-l) with l = 1,...,ylags.

4. (logs): Logs: It uses forecasts of the logarithm of the dependent varible, i.e. ln(y(t+h)) with h = 0...hor.
When the option ylags() is specified, it includes lags of the logarithm of the variable, i.e. ln(y(t-l)) with l = 1,...,ylags.

5. (logs diff): Log-differences: It uses forecasts of the dependent variable in differences of its natural logarithm,
i.e. ln(y(t+h)) - ln(y(t+h-1)) with h = 0...hor. When the option ylags() is specified, it includes lags of the variable in log-differences,
i.e. ln(y(t))-ln(y(t-l)) with l = 1,...,ylags.

6. (logs cmlt): Cumulative log-differences: It uses forecasts of the dependent variable in cumulative differences of its natural logarithm,
i.e. ln(y(t+h)) - ln(y(t-1)) with h = 0...hor. When the option ylags() is specified, it includes lags of the variable in log-differences,
i.e. ln(y(t))-ln(y(t-l)) with l = 1,...,ylags.

Estimation Method:

met(string) Specifies the estimation method. The default is xtreg when using panel data and reg
when using time-series data. Any estimation method with a standard syntax is allowed. Additionally, the command allows
to use the instrumental variable commands ivregress and xtivreg and other IV methods with a similar syntax.
In the specific case of ivregress, the user also has to specify the "estimator" within the met() option
in the following way:
met(ivregress estimator), where estimator could be either on of 2sls, liml or gmm.
When any IV method is specified, a list of instruments must also be provided through the option instr(varlist).

instr(varlist) Specifies the variables to use as instruments for the impulse (shock) variable when using an
instrumental variable method such as ivregress or xtivreg. The shock variable must be defined as
in any of the model specification available options.

model_options Specifies any other estimation options specific to the method used and not defined elsewhere.
If the user wants to specify any methodological option corresponding to the estimation method being used, she only has to
enter them alongside the rest of locproj options.

hopt(string) Specifies any methodological option that depends directly on the horizon of the IRF, i.e. any option
that must change with every step/horizon of the IRF h = 0...hor.

noisily If this option is specified, the command displays a regression output for each one of the horizons. If this option
is not specified the command only returns a matrix with the IRF, its standard error and the confidence bands.

stats If this option is specified, the command displays a table with the summary statistics of the estimated regression
at each step/horizon. The table includes the number of observations, the R-squared or pseudo-R-squared, the F-statistic or Chi2-statistic,
and the p-value (prob) of the respective statistic.

IRF Options:

conf(numlist) Specifies one or (max) two confidence levels for calculating the confidence bands. The default is 95%.

saveirf If this option is specified, the IRF, its standard error and the confidence bands are saved as new variables, otherwise
no new variables are created. If this option is specified, the command assigns a default name to the new generated variables.

irfname(string) Specifies a name/prefix for the new IRF variable and the other new generated variables (standard error
and confidence bands).

fact(real) Specifies a factor for scaling the IRF, for instance, if the user wants to express the log difference transformation
in percentage terms, this option should be specified as fact(100).

Graph Options:

nograph If this option is specified a graph is not displayed.

zero If this option is specified the graph includes a dashed line for the value 0.

title(string) Specifies a title for the IRF graph.

lcolor(string) Specifies a color for the IRF line and the confidence bands.

label(string) Specifies a label for the IRF line in the IRF graph.

ttitle(string) Specifies a name for the time axis in the IRF graph.

grname(string) Specifies a graph name that could be used, for instance, when combining various graphs.

grsave(string) Specifies a file name and path that should be used to save the IRF graph on the disk.

as(string) Specifies the desired file format of the saved graph.

gropt(string) Specifies any other graph options not defined elsewhere.

Stored results

locproj stores the following in e():

Matrices

e(irf) A matrix including the Impulse Response Function (IRF), its standard error and its confidence interval.

e(stats) A matrix including the regression statistics by each step/horizon.

Name of Generated Variables if no name is defined:

_birf estimated impulse response function (IRF).

_seirf IRF's standar error

_irfup IRF's upper confidence interval

_irflo IRF's lower confidence interval

_irfup2 second IRF's upper confidence interval

_irflo2 second IRF's lower confidence interval

Name of Generated Variables if the name given to the IRF is "irfname":

irfname estimated impulse response function (IRF).

irfname_se IRF's standar error

irfname_lo IRF's lower confidence interval

irfname_up IRF's upper confidence interval

irfname_up2 second IRF's upper confidence interval

irfname_lo2 second IRF's lower confidence interval

Example 1. Use of locproj to replicate the IRFs in the "simple time series example: lp-example" do-file in Jordà website

(https://sites.google.com/site/oscarjorda/home/local-projections?pli=1)

. use AED_INTERESTRATES.dta

Example 1.1 Defining the basic specific options

What the automatic vs. explicit specification means is that the user can let locproj interpret in an automatic way
which variables in the provided varlist correspond to the dependent variable, which one is the shock,
which ones are control variables, and also which ones are just lags of each type of variable. Alternatively,
in more complicated cases, the user can specify all those details in a explicit way using the available options for
such cases.

The simplest local projection specification in which the response variable is gs10 and the shock variable is gs1 would be
(automatic specification):

. locproj gs10 gs1

Which would also be equivalent to the following (explicit specification):

. locproj gs10, shock(gs1)

A more interesting specification would include lags of the dependent variable and of the shock, and would specify a response horizon.
All the next six examples do those things and are exactly equivalent:

Automatic specification

. locproj gs10 l(0/4).gs1 l(1/3).gs10, hor(12)

. locproj l(0/3).gs10 l(0/4).gs1, hor(12)

. locproj gs10 l(1/3).gs10 l(0/4).gs1, hor(12)

Explicit or intermmediate specification

. locproj gs10, shock(gs1) ylags(3) slags(4) hor(12)

. locproj gs10 l(1/3).gs10, shock(gs1) slags(4) hor(12)

. locproj gs10 l(0/4).gs1, ylags(3) hor(12)

Example 1.2. A simple non-linear example

If we want to specify a very simple non-linear shock, for instance, a quadratic term of the variable gs1, we only need to add
such additional variable in the shock() option:

. gen gs1_2 = gs1^2

. locproj gs10, shock(gs1 gs1_2) ylags(3) slags(4) hor(12)

Alternatively we can include an additional interaction term of two continuous variables in the shock() option:

. locproj gs10, shock(gs1 c.gs1#c.gs1) ylags(3) slags(4) hor(12)

locproj will take all the variables that are defined in the shock() option and the resulting IRF will correspond to the
addition of the individual effect of those variables, for instance, in this example, the IRF would be the addition of the estimated
coefficients of the variables gs1 and gs1_2, or the variables gs1 and c.gs1#c.gs1.

Example 1.3. Estimation method options

The Jordà example requires using Newey-West as the estimation method, which consequently requires specifying that the option
"lag" in the Newey-West command should depend on the horizon of the IRF in the following way:

. locproj gs10 l(0/4).gs1 l(1/3).gs10, h(12) met(newey) hopt(lag)

Example 1.4. Displaying all the regression outputs

If we want to take a look at the regression output for each one of the horizons of the IRF we can use the options noisily and stats.
The regression outputs displayed are not the direct outputs from whatever estimation method we are using, but a simplified output table.
The reason for this is that locproj uses temporary variables whose given names do not have any meaning and would be difficult to
understand. locproj generates a new output table with variable names related to the variable list defined by the user.

. locproj gs10 l(0/4).gs1, h(12) m(newey) hopt(lag) yl(3) noisily

The stats option generates a table with each regression statistics for every horizon, i.e. number of observations, R-squared
or pseudo-R-squared, F-statistic or Chi2-statistic and their respective p-values.

. locproj gs10 l(0/4).gs1, h(12) m(newey) hopt(lag) yl(3) stats

Example 1.5. Use of the transformation options

If we want to run the LP in differences (without using the already existing variables) we can use the option transf()
together with the ylags() option to define the number of lags of the dependent variable (notice that in this first
example we are also differentiating the shock variable gs1):

. locproj gs10 l(0/4).d.gs1, h(12) m(newey) hopt(lag) transf(diff) yl(3)

Alternatively, the model in differences using the already differentiated variables in the dataset without using
the transformation option would be:

. locproj dgs10 l(0/4).dgs1 l(1/3).dgs10, hor(12) met(newey) hopt(lag)

In the case of running the LP in cumulative differences we would have to use the option transf(cmlt), again, together with
the ylags() option:

. locproj gs10 l(0/4).d.gs1, h(12) m(newey) hopt(lag) tr(cmlt) yl(3)

In the next examples we use the transformation in difference of logarithm and cumulative log-differences.
In order to express the result in percentage terms, we also make use of the option fact() and we scale the response
by a factor of 100. We are going to estimate the IRF of a shock of the variable aaa into the variable
baa:

. gen lnaaa = ln(aaa)

log-differences:

. locproj baa l(0/4).lnaaa, h(12) m(newey) hopt(lag) transf(logs diff) yl(3) fact(100)

cumulative log-differences:

. locproj baa l(0/4).lnaaa, h(12) m(newey) hopt(lag) transf(logs cmlt) yl(3) fact(100)

Example 1.6. Changing the confidence level or using more than one level

By default the confidence level for the confidence bands is 95%. If we want to change it, we can use the conf() option
which admits a maximum of two levels and only admits integer values:

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) conf(90)

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) conf(66 99)

Example 1.7. Saving the IRF results into new variables

If we want to save the estimated IRF into a new variable that can be used later, we can use it through the options saveirf and irfname().
If we just type saveirf, locproj generates four (or six) new variables with the IRF, its standard error and the confidence bands.
locproj uses some predetermined default names to save the corresponding variables (_irf, _seirf, _irf_lo and _irf_up), but if we want
to give them a name of our preference (e.g. newirf), we can do it through the option irfname():

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) saveirf

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) save irfname(newirf)

Example 1.8. Some graph options

If we do not want locproj to produce a graph, we just have to type nograph:

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) nograph

In the following example we are going to produce a graph in which a dashed-line with the value of zero is included, we are goint to give
the graph the tittle "LP Example", include a label "1 Year Treasury IRF", change the color of the IRF line and its confidence interval
to red instead of blue, and define the time axis as "Number of Days":

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) zero title("LP Example") label("1 Year Treasury IRF") lcolor(red) ttitle("Number of Days") conf(66 95)

Next, we are going to give the graph a name, we are going to save it in a folder in our disk as a png file named "example1":

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) zero title(LP Example) grname(Example1) grsave(C:\Documents\example1.png) as(png)

We can also add other graph options inside the gropt() option, for instance, we can define the labels of the y-axis and change the
background color to white:

. locproj gs10 l(0/4).dgs1, h(12) m(newey) hopt(lag) tr(diff) yl(3) zero title(LP Example) gropt(graphregion(fcolor(white)) ylabel(-0.25(0.25)1))

We can also combine the results of different IRFs into a single graph using the post-estimation command lpgraph. See lpgraph for specific help about using the command lpgraph.

Example 2. Use of locproj to replicate the IRFs in the "panel data example: lp_example_panel" do-file in Jordà website

. use "http://data.macrohistory.net/JST/JSTdatasetR5.dta"

We need to declare the panel data variables:

. xtset ifs year

For reproducing the first example in the Panel data example in Jordà website, we first need to generate some variables:

. gen lgdpr = 100*ln(rgdppc*pop)

. gen lcpi = 100*ln(cpi)

. gen dlgdpr = d.lgdpr

. gen dstir = d.stir

Throughout this example we assume that the real GDP (GDPR) responds with a lag to shocks in the short-term interest rate (STIR) and to shocks
in consumer prices (CPI); CPI responds with a lag to shocks in STIR and contemporaneously to shocks in GDPR; STIR responds contemporaneously
to shocks in GDPR and CPI.

Now, we can reproduce the response of real GDP to a 1pp shock to the real short-term interest rate. The next five examples are exactly equivalent.
They differ in how to define the shock variable and its lags, and the dependent variable and its lags. In all of them, the estimation method is xtreg,
they use the "fixed-effect" estimator and a cluster-robust covariance matrix. They use a confidence level of 90%. They define the values of the y-axis,
they y-axis title, the x-axis label and the title of the graph:

Using the transformation option transf() and the fully explicit options:

. locproj lgdpr, s(l.d.stir) c(l(1/3).d.lcpi) tr(diff) h(4) yl(3) sl(2) fe cluster(iso) z conf(90) gropt(ylabel(-0.4(0.2)0.2) ytitle(Percent)) tti(Year) title(Response of GDPR to 1pp shock to STIR (Cholesky))

Using the existing differentiated variables and a fully automatic specification:

. locproj l(0/3).dlgdpr l(1/3).dstir l(1/3).d.lcpi, fe cluster(iso) h(4) z conf(90) gropt(ylabel(-0.4(0.2)0.2) ytitle(Percent)) tti(Year) title(Response of GDPR to 1pp shock to STIR (Cholesky))

Using the transformation option transf() and the fully automatic options:

. locproj l(0/3).lgdpr l(1/3).d.stir l(1/3).d.lcpi, fe cluster(iso) tr(diff) h(4) z conf(90) gropt(ylabel(-0.4(0.2)0.2) ytitle(Percent)) tti(Year) title(Response of GDPR to 1pp shock to STIR (Cholesky))

Using the transformation option transf() and a combination of automatic and explicit options:

. locproj lgdpr l.d.stir l(1/3).d.lcpi, h(4) yl(3) sl(2) fe cluster(iso) tr(diff) z conf(90) gropt(ylabel(-0.4(0.2)0.2) ytitle(Percent)) tti(Year) title(Response of GDPR to 1pp shock to STIR (Cholesky))

In all the previous equivalent five examples, the shock variable is included with a lag and no contemporaneous term (L.D.stir), and thus, the response at hor = 0 is equal to 0 and an extra period is added to
the final horizon period.

Alternatively, in the next example, when estimating the response of CPI to the short-term interest rate, we just need to change the dependent variable to CPI instead of GDPR in any of the previous examples.
We also need to change the number of lags of the control variable, which in this case is the GDP, from (0/3) to (1/3) in order to specify a Cholesky decomposition.

. locproj lcpi, s(l.d.stir) c(l(0/3).d.lgdpr) tr(diff) h(4) yl(3) sl(2) fe cluster(iso) z conf(90) gropt(ytitle(Percent)) tti(Year) title(Response of CPI to 1pp shock to STIR (Cholesky))

Finally, in the final exercise, the shock variable is the same as the dependent variable, so it is more convenient to use an explicit option
for the shock and its lags.Moreover, the first response at hor = 0 is equal to 1 since the response variable and the shock are the same
at that horizon period.

. locproj d.stir l(0/3).d.lcpi l(0/3).d.lgdpr, s(d.stir) sl(3) h(4) fe cluster(iso) z conf(90) gropt(ytitle(Percent)) tti(Year) title(Response of STIR to 1pp shock to STIR (Cholesky))

Example 3. Use of locproj to replicate the IRFs in the "LPIV example: lpiv_example" do-file in Jordà website

For this example we use the databases RR_monetary_shock_quarterly.dta and lpiv_15Mar2022.dta from Jordà website.

. use RR_monetary_shock_quarterly.dta

. merge 1:1 date using lpiv_15Mar2022.dta, nogen

Next, we keep only nonmissing observations in resid_full i.e. 1969m1 - 2007m12

. keep if resid_full != .

We need to declare the time series variable

. tsset date

For estimating the IRF using OLS we need to take into consideration that in the example, the response horizon starts at hor = 1. However, for exactly replicating the example, we need to use the one-step ahead
forecast of UNRATE as the dependent variable instead of UNRATE. We also use Newey-West as the variance-covariance estimation method, which requires defining the option lag() in Newey-West, and thus, we need to use the option
hopt() in our locproj command:

. locproj f.UNRATE DFF l(1/4).DFF l(1/4).UNRATE, h(0/15) hopt(lag) m(newey) z

For replicating the instrumental variable IRF example, we use the option met() specifying that the method is ivregress gmm. Notice that in this case the meth() option should include the gmm sub-method.
Additionally, we need to define the instrument(s) for the shock, which in this case corresponds to the variable resid_full. Moreover, we define as an estimation method option the variance-covariance estimator hac nwest in the following way:

. locproj f.UNRATE l(0/4).DFF l(1/4).UNRATE, h(0/15) met(ivregress gmm) instr(resid_full) vce(hac nwest) z

In this particular case, if we want to replicate the Jordà example using the ylags() option would be a bit tricky, since the dependent variable
is f.UNRATE, but the lags of the variable UNRATE in the original specification are (1/4).
If we were to specify ylags(4) then we would actually be including lags (0/3)
given the forecast of the dependent variable. Therefore, in this case, it would be more convenient to include the lags of the variable UNRATE
in the main varlist or even as control variables with the option controls():

. locproj f.UNRATE l(1/4).UNRATE, s(DFF) sl(4) h(0/15) met(ivregress gmm) instr(resid_full) vce(hac nwest) z

. locproj f.UNRATE, s(DFF) sl(4) controls(l(1/4).UNRATE) h(0/15) met(ivregress gmm) instr(resid_full) vce(hac nwest) z

Example 4. Non-linear effects and interactions: Using the option lcs()

For Examples 4 and 5 we are going to use need the JST dataset and the "RecessionDummies" dataset that contains data on recessions and financial crises.

. use "http://data.macrohistory.net/JST/JSTdatasetR5.dta"

. merge 1:1 year iso using "RecessionDummies.dta", nogen

We need to declare the panel data variables:

. xtset ifs year

We also need to drop WWI and WWII years from JST dataset:

. drop if year >=1914 & year <=1919

. drop if year >=1939 & year <=1947

In the "RecessionDummies" database, the variable F is a Financial Crisis dummy variable, while the variable N is a Normal Recession dummy variable.
In this example we want to look at the cumulative IRF of real GDP per capita to a financial crisis, while controling for the effect of normal recessions,
and viceversa. Thus, we need to use the option lcs() since the effect we are looking for is the sum of the constant term plus the effect of
F=1 or N=1.

Therefore, in the following examples we include the expression "_cons + l.F" and "_cons + l.N" inside the option lcs(). Notice that when we use
the option lcs() the order of the variables l.F and l.N in the main syntax does not matter, since the shock that locproj evaluates
is only determined by what it is defined by the option lcs():

. locproj rgdppc l.F l.N, fe robust tr(logs cmlt) h(4) z f(100) lcs(_cons + l.F)

. locproj rgdppc l.F l.N, fe robust tr(logs cmlt) h(4) z f(100) lcs(_cons + l.N)

We can include more complicated interactions, for instance we can interact the effect of Financial Crisis (F) or Normal Recessions (N) with the
public debt-to-GDP ratio and evaluate the IRF at different levels of such ratio.

We first estimate the mean and standard deviation of the Public Debt-to-GDP ratio:

. sum debtgdp

. sca dm=r(mean)

. sca dsd=r(sd)

In the command syntax we include the interaction of the public debt ratio with the financial crises and the normal recessions. Then in the lcs()
we enter the expansion of the interaction between financial crises and the debt ratio (1.l.F#c.l.debtgdp), multiplied by the mean and std. deviaton of
the ratio (dm+dsd):

. locproj rgdppc l.N l.F l.(N#c.debtgdp F#c.debtgdp), fe robust tr(logs cmlt) nograph f(100) lcs(_cons+l.F+1.l.F#c.l.debtgdp*(dm+dsd))

In a similar way for normal recessions:

. locproj rgdppc l.N l.F l.(N#c.debtgdp F#c.debtgdp), fe robust tr(logs cmlt) nograph f(100) lcs(_cons+l.N+1.l.N#c.l.debtgdp*(dm+dsd))

Example 5. Non-linear effects, interactions and binary dependent variable: Using the option margins

We need again the JST and the "RecessionDummies" datasets:

. use "http://data.macrohistory.net/JST/JSTdatasetR5.dta"

. merge 1:1 year iso using "RecessionDummies.dta", nogen

. xtset ifs year

We also need to drop WWI and WWII years from JST dataset:

. drop if year >=1914 & year <=1919

. drop if year >=1939 & year <=1947

In our first example, we will estimate the IRF of the probability of a banking crisis to an increase in the USA short-term interest rate.
Our dependent variable in this case is the dummy variable crisisJST that is equal to 1 for banking crises.

We need to generate a new variable stir_us with the US interest rate as a common variable for all the countries in the sample, in order
to estimate the response of the probability of a banking crisis to the short-term interest rate in the US:

. gen stir_us0=stir if iso=="USA"

. egen stir_us=mean(stir_us0), by(year)

Now we are going to estimate the IRF using the option margins. The option margins estimates the marginal effect of a unit of
our shock variable (stir_us) on the probability of a banking crisis, which is our dependent (response) variable.
We are using as estimation method the command xtlogit with fixed effects:

. locproj crisisJST l(0/2).stir_us, margins m(xtlogit) fe

We can also interact the shock variable with a dummy variable, for instance, whether a country has a "PEG" foreign exchange regime.

The option margins allow us to estimate a separate IRF for each category of the dummy variable PEG. For doing that we need to use the option
mrfvar(). In this option we need to specify the expansion of the categorical variable that has been interacted with our shock variable.
We also need to use the explicit option to define which variable is our shock without any interaction term, since the command margins
does not accept an interaction term expression in its dydx() option:

. locproj crisisJST peg#c.l(0/2).stir_us, s(stir_us) margins m(xtlogit) fe mrfvar(1.peg)

. locproj crisisJST peg#c.l(0/2).stir_us, s(stir_us) margins m(xtlogit) fe mrfvar(0.peg)

Alternatively, instead of entering the shock variable as peg#c.l(0/2).stir_us in the main syntax, we can enter the expression
l(0/2).stir_us peg#c.l(0/2).stir_us and in this way the command would use the variable stir_us as the shock variable,
whithout the need to specify it through the locproj option shock():

. locproj crisisJST l(0/2).stir_us peg#c.l(0/2).stir_us, margins m(xtlogit) fe mrfvar(1.peg)

. locproj crisisJST l(0/2).stir_us peg#c.l(0/2).stir_us, margins m(xtlogit) fe mrfvar(0.peg)

References

"Jordà, Òscar. "Estimation and inference of impulse responses by local projections." American Economic Review 95, no. 1 (2005): 161-182."

https://sites.google.com/site/oscarjorda/home/local-projections?pli=1

Author

Alfonso Ugarte-Ruiz
alfonso.ugarte@bbva.com