*! version 2.2.0 Mar 15 2023
help xtevent

Title

xtevent -- Panel Event Study Estimation

Syntax

xtevent
depvar [indepvars]
[if] [in]
,
policyvar(varname)
panelvar(varname)
timevar(varname)
[options]

Main
* policyvar(varname) policy variable

panelvar(varname) variable that identifies the panels

timevar(varname) variable that identifies the time periods

window(numlist) # of periods in the estimation window

pre(integer) # of periods with anticipation effects

post(integer) # of periods with policy effects

overidpre(integer) # of periods to test pre-trends

overidpost(integer) # of periods to test effects leveling off

norm(integer) event-time coefficient to normalize to 0

proxy(varname) proxy for the confound

proxyiv(string) instruments for the proxy variable

nofe omit panel fixed effects

note omit time fixed effects

impute(type [, saveimp]) impute missing values in policyvar

static estimate static model

diffavg estimate the difference in averages between the post and pre-periods

trend(#1 [, subopt]) extrapolate linear trend from time period #1 before treatment

savek(stub [, subopt]) save time-to-event, event-time, trend, and interaction variables

kvars(stub) use previously generated event-time variables

reghdfe use reghdfe for estimation

addabsorb(varlist) absorb additional variables in reghdfe

repeatedcs indicate that the dataset in memory is repeated cross-sectional

cohort(varname) variable that identifies the cohorts for Sun and Abraham (2021) estimation

control_cohort(varname) variable that identifies the control cohort for Sun and Abraham (2021) estimation

plot display plot. See xteventplot.

additional_options additional options to be passed to the estimation command

depvar and indepvars may contain time-series operators; seetsvarlist.

depvar and indepvars may contain factor variables; seefvvarlist.

* policyvar(varname) is required. window(integer) is required unless static, or pre, post,
overidpre, and overidpost are specified. panelvar(varname) and timevar(varname) are required if the data
have not been xtset, otherwise they are optional. See xtset.

See xteventtest for hypothesis testing after estimation and xteventplot for plotting after estimation.

Description

xtevent estimates the effect of a policy variable of interest on a dependent variable using a panel event-study
design. Additional control variables can be included in varlist. The command allows for estimation when a pre-trend
is present usingthe instrumental variables estimator of Freyaldenhoven et al. (2019). It also allows estimation in
settings with heterogeneous effects by cohort using the Interaction Weighted Estimator of Sun and Abraham (2021).

Options

Main

policyvar(varname) specifies the policy variable of interest. policyvar() is required.

Estimation

panelvar(varname) specifies the cross-sectional identifier variable that identifies the panels. panelvar() is required if the data
have not been previously xtset. See xtset.

timevar(varname) specifies the time variable. timevar() is required if the data have not been previously xtset. See
xtset.

window(numlist) specifies the window around the policy change event to estimate dynamic effects. If a single positive integer k>0
is specified, the estimation will use a symmetric window of k periods around the event. For example, if k = 2, there will be five
coefficients in the window (-2,-1,0,1,2) and two endpoints (-3+, 3+). If two distinct integers k1<=0 and k2>=0 are specified, the
estimation will use an asymmetric window with k1 periods before the event and k2 periods after the event. For example, with k1 = -1
and k2 = 2, there will be four coefficients in the window (-1,0,1,2) and two endpoints (-2+,3+). window() is required unless
static is specified, or if the estimation window is specified using options pre(), post(), overidpre(),
and overidpost() (See below).

pre,
post,
overidpre and
overidpost offer an alternative way to specify the estimation window:

pre is the number of pre-event periods where anticipation effects are allowed. With window, pre is 0.

post is the number of post-event periods where policy effects are allowed. With window, post is the number
of periods after the event minus 2.

overidpre is the number of pre-event periods for an overidentification test of pre-trends. With window, overidpre
is the number of periods before the event.

overidpost is the number of post-event periods for an overidentification test of effects leveling off. With window,
overidpost is 2.

You can specify either window or
pre,
post,
overidpre and
overidpost.

norm(integer) specifies the event-time coefficient to be normalized to 0.
The default is to normalize the coefficient on -1.

proxy(varlist) specifies proxy variables for the confound to be included.

proxyiv(string) specifies instruments for the proxy variable for the policy. proxyiv() admits three syntaxes to use
either leads of the policy variable or aditional variables as instruments. The default is to use leads of the difference of the
policy variable as instruments, selecting the lead with the strongest first stage.

proxyiv(select) selects the lead with the strongest first stage among all possible leads of the differenced policy variable to
be used as an instrument.
proxyiv(select) is the default for the one proxy, one instrument case, and it is only available in this case.

proxyiv(# ...) specifies a numlist with the leads of the differenced policy variable as instruments. For example,
proxyiv(1 2) specifies that the two first leads of the difference of the policy variable will be used as instruments.

proxyiv(varlist) specifies a varlist with the additional variables to be used as instruments.

nofe excludes panel fixed effects.

note excludes time fixed effects.

impute(type [, saveimp]) imputes missing values in policyvar and uses this new variable as the policyvar for estimation.
type determines the imputation rule. The suboption saveimp adds the new variable to the database as
policyvar_imputed. The following imputation types can be implemented:

impute(nuchange) imputes missing values in policyvar according to no-unobserved change: It assumes that,
for each unit: i) in periods before the first observed value, the policy value is the same as the first observed value; and
ii) in periods after the last observed value, the policy value is the same as the last observed value.

impute(stag) applies no-unobserved change if policyvar satisfies staggered-adoption assumptions for all units:
i) policyvar must be binary; and ii) once policyvar reaches the adopted-policy state, it never reverts to the
unadopted-policy state. See Freyaldenhoven et al. (2019) for detailed explanation of the staggered case. Additionally in
the policyvar, for each unit: i) the first-observed value must be the unadopted-policy-state value, and the last-observed
value must be the adopted-policy-state value; or ii) all policy values in the observed data range must be either
adopted-policy-state values or unadopted-policy-state values.

impute(instag) applies impute(stag) and additionally imputes missing values inside the observed data range: a missing
value or a group of them will be imputed only if they are both preceded and followed by the unadopted-policy state or by the
adopted-policy state.

static estimates a static panel data model and does not generate or plot event-time dummies. static is not allowed with
window or diffavg.

diffavg calculates the difference in averages between the post-event estimated coefficients and the pre-event estimated
coefficients periods. It also calculates its standard error with lincom. diffavg is not allowed with static.

trend(#1 [, subopt]) extrapolates a linear trend between time periods from period #1 before the policy change, as in
Dobkin et al. (2018). The estimated effect of the policy is the deviation from the extrapolated linear trend. #1 must be less than -1. The
following suboptions can be specified:

method(string) sets the method to estimate the linear trend. It can be Ordinary Least Squares (ols) or Generalized Method of
Moments (gmm). (ols) omits the event-time dummies from trend(#1) to -1 and adds a linear trend (_ttrend) to the regression.
(gmm) uses the GMM to compute the trend for the event-time dummy coefficients. The default is method(gmm).

saveoverlay saves estimations for the overlay plot produced by xteventplot, overlay(trend).

savek(stub [, subopt]) saves variables for time-to-event, event-time, trend, and interaction variables. Event-time dummies are stored as
stub_eq_m# for the dummy variable # periods before the policy change, and stub_eq_p# for the dummy variable # periods after the
policy change. The dummy variable for the policy change time is stub_eq_p0. Event time is stored as stub_evtime. The trend is stored
as stub_trend. For estimation with the Sun and Abrahm (2021) method, such that cohort and control_cohort are active, the
interaction variables are stored as stub_m#_c# or stub_p#_c#, where c# indicates the cohort. The following suboptions can be
specified:

noestimate saves variables for event-time dummies, event-time and trends without estimating the model. This is useful if the
users want to customize their regressions and plots.

saveinteract saves interaction variables if cohort and control_cohort are specified. noestimate and
saveinteract cannot be specified simultaneously.

saveinteract saves interaction variables if cohort and control_cohort are specified. noestimate and saveinteract cannot be specified simultaneously.

usek(stub) uses previously used event-time dummies saved with prefix stub. This can be used to speed up estimation.

reghdfe uses reghdfe for estimation, instead of areg, ivregress, and xtivreg. reghdfe is useful for large
datasets. By default, it absorbs the panel fixed effects and the time fixed effects. For OLS estimation, the reghdfe
option requires reghdfe and ftools to be installed. For IV estimation, it also requires ivreghdfe and ivreg2
to be installed. Note that standard errors may be different and singleton clusters may be dropped using reghdfe.
See Correia (2017).

addabsorb(varlist) specifies additional fixed effects to be absorbed when using reghdfe. By default, xtevent includes time
and unit fixed effects. addabsorb requires reghdfe.

repeatedcs indicates that the dataset in memory is repeated cross-sectional. In this case, panelvar should indicate the groups
at which policyvar changes. For instance, panelvar could indicate states at which policyvar changes, while the observations
in the dataset should be individuals in each state. There is a faster method to estimate the event study in a repeated cross-sectional
dataset, which involves using get_unit_time_effects first, and then xtevent. See get_unit_time_effects. For fixed-effects
estimation, repeatedcs enables reghdfe.

cohort(varname) specifies the variable that identifies the cohort for each unit. cohort and control_cohort indicate xtevent
to estimate the event-time coefficients with the Interaction-Weighted Estimator proposed by Sun and Abraham (2021). cohort requires the
Stata module avar; click here to install or type "ssc install avar" from inside Stata.

control_cohort(varname) specifies the binary variable that identifies the control cohort. cohort and control_cohort indicate
xtevent to estimate the event-time coefficients with the Interaction Weighted Estimator proposed by Sun and Abraham (2021).
control_cohort requires the Stata module avar; click here to install or type "ssc install avar" from
inside Stata.

plot displays a default event-study plot with 95% and sup-t confidence intervals (Montiel Olea and Plagborg-Møller 2019).
Additional options are available with the postestimation command xteventplot.

additional_options: Additional options to be passed to the estimation command. When proxy is specified, these options are passed
to ivregress. When reghdfe is specified, these options are passed to reghdfe. Otherwise, they are passed to areg or
to regress if nofe is specified. This is useful to calculate clustered standard errors or to change regression reporting. Note
that two-way clustering is allowed with reghdfe.

Examples

Setup

. webuse nlswork

year variable has many missing observations.

Create a time variable that ignores these gaps.

. by idcode (year): gen time=_n

. xtset idcode time

Generate a policy variable that follows staggered adoption.

. by idcode (time): gen union2 = sum(union)

. replace union2 = 1 if union2 > 1

Estimate a basic event study with clustered standard errors.

Impute the policy variable assuming no unobserved chhanges

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) cluster(idcode) impute(nuchange)

Omit unit and time fixed effects

Impute the policy variable verifying staggered adoption

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) cluster(idcode) nofe note impute(stag)

Save event-time dummies without estimating the model

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) cluster(idcode) impute(stag) savek(a, noe)

Change the normalized coefficient and use an asymmetric window

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) cluster(idcode) w(-3 1) norm(-2) impute(stag)

Adjust the pre-trend by estimating a linear trend by GMM

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(2) cluster(idcode) trend(-2, method(gmm)) impute(stag)

Freyaldenhoven, Hansen and Shapiro (2019) estimator with proxy variables

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) vce(cluster idcode) proxy(wks_work) impute(stag)

Include additional proxy variables, and additional policy variable leads as instruments

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) vce(cluster idcode) proxy(wks_work hours) proxyiv(1 2) impute(stag)

reghdfe and two-way clustering

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure , pol(union2) w(3) cluster(idcode year) reghdfe proxy(wks_work) impute(stag)

Interaction Weighted Estimator proposed by Sun and Abraham (2021)

First, create the control and control cohort variables

Generate the variable that indicates cohort

. gen timet=year if union2==1

. by idcode: egen time_of_treat=min(timet)

Generate the variable that indicates the control cohort. We use the never-treated units as the control cohort

. gen never_treat=time_of_treat==.

. xtevent ln_w age c.age#c.age ttl_exp c.ttl_exp#c.ttl_exp tenure, policyvar(union2) window(3) impute(stag) vce(cluster idcode) cohort(time_of_treat) control_cohort(never_treat)

Saved Results

xtevent saves the following in e():

Scalars

e(lwindow) left endpoint for estimation window

e(rwindow) right endpoint for estimation window

Macros

e(names) names of the variables for the event-time dummies

e(y1) mean of dependent variable et event-time = -1

e(x1) mean of proxy variable et event-time = -1, when only one proxy is specified

e(trend) "trend" if estimation included extrapolation of a linear trend

e(cmd) estimation command: can be regress, areg, ivregress, xtivreg, or reghdfe

e(df) degrees of freedom

e(komit) list of lags/leads omitted from regression

e(kmiss) list of lags/leads to be omitted from plot

e(method) "ols" or "iv"

e(cmd2) "xtevent"

e(depvar) dependent variable

e(pre) number of periods with anticipation effects

e(post) number of periods with policy effects

e(overidpre) number of periods to test for pre-trends

e(overidpost) number of periods to test for effects leveling off

e(stub) prefix for saved event-time dummy variables

Matrices

e(b) coefficient vector

e(V) variance-covariance matrix

e(delta) coefficient vector of event-time dummies

e(Vdelta) variance-covariance matrix of the event-time dummies coefficients

e(deltax) coefficients for proxy event-study to be used in overlay plot

e(deltaxsc) scaled coefficients for proxy event-study to be used in overlay plot

e(deltaov) coefficients for event-study to be used in overlay plot

e(Vdeltax) variance-covariance matrix of proxy-event study coefficients for overlay plot

e(Vdeltax) variance-covariance matrix of event-study coefficients for overlay plot

e(mattrendy) matrix with y-axis values of trend for overlay plot, only when trend(#1) is specified

e(mattrendx) matrix with x-axis values of trend for overlay plot, only when trend(#1) is specified

e(Sigma_ff) variance estimate of the cohort share estimators, only when cohort and control_cohort are specified

e(ff_w) Each column vector contains estimates of cohort shares underlying the given relative time, only when cohort and control_cohort are specified

e(V_interact) each column vector contains variance estimate of the cohort-specific effect estimator for the given relative time, only when cohort and control_cohort are specified

e(b_interact) each column vector contains estimates of cohort-specific effect for the given relative time, only when cohort and control_cohort are specified

Functions

e(sample) marks estimation sample

Authors

Simon Freyaldenhoven, Federal Reserve Bank of Philadelphia.

simon.freyaldenhoven@phil.frb.org

Christian Hansen, University of Chicago, Booth School of Business.

chansen1@chicagobooth.edu

Jorge Pérez Pérez, Banco de México.

jorgepp@banxico.org.mx

Jesse Shapiro, Harvard University and NBER.

jesse_shapiro@fas.harvard.edu

Support

For support and to report bugs please email Jorge Pérez Pérez, Banco de México.

jorgepp@banxico.org.mx

xtevent can also be found on GitHub.

References

Correia, S. (2017) . "Linear Models with High-Dimensional Fixed Effects: An Efficient and Feasible Estimator" Working Paper. http://scorreia.com/research/hdfe.pdf

Dobkin, C., Finkelstein A., Kluender. R., and Notowidigdo, M. J. (2018) "The Economic Consequences of Hospital Admissions."
American Economic Review, 108 (2): 308-52.

Freyaldenhoven, S., Hansen, C. and Shapiro, J. (2019) "Pre-event Trends in the Panel Event-study Design" American Economic Review, 109 (9):
3307-38.

Freyaldenhoven, S., Hansen, C., Pérez Pérez, J. and Shapiro, J. (2021) "Visualization, Identification,
and Estimation in the Linear Panel Event-study Design". Working paper.

Montiel Olea, J.L. and Plagborg-Møller, M. (2019) "Simultaneous confidence bands: Theory, implementation, and an application to SVARs".
Journal of Applied Econometrics, 34: 1– 17.

Sun, L. and Abraham, S. (2021) "Estimating Dynamic Treatment Effects in Event Studies with Heterogeneous Treatment Effects".
Journal of Econometrics, 225 (2): 175-199.

Acknowledgements

We are grateful to Veli Andirin, Mauricio Cáceres, Richard Calvo, Constantino Carreto, Kathryn Dawson-Townsend, Theresa Doppstadt,
Ángel Espinoza, Miguel Fajardo-Steinhauser Samuele Giambra, Ray Huang, Chandra Kant Dhakal, Panagiotis Konstantinou, Per Lidbom,
Isabel Z. Martínez, Diego Mayorga, Eric Melse, Stefano Molina, Asjad Naqvi, Anna Pasnau, Nathan Schor, Emily Wang, Matthias Weigand,
and Wenli Xu for contributions to development and for testing earlier versions of this command.