csdid: Difference in Difference with Multiple periods estimator

Syntax

csdid
depvar [indepvars]
[if] [in] [weight],
[ivar(varname)]
time(varname) gvar(varname)
[ options ]

Options

Model Specification

depvar Declares the dependent variable or outcome of interest.

indepvar Declares the independent variable or controls. Depending
on the estimation method, all declared variables will be used for the outcome regression model,
the propensity score estimator, or both.

One can use factor notation. Only base period values are used in the model estimation.

DiD Model Specification

ivar(varname) Variable used as panel identifier. e.g., country. When declared, the model assumes the data
has a panel structure, and will apply panel estimators. When no variable is declared the command assumes data are
repeated crosssection (RC), and applies RC estimators.

time(varname) Variable to identify time. e.g., year. Periods do not need to be consecutive, but
the variable is expected to be strictly positive, with regular gaps.

gvar(varname) Variable identifying treatment groups or cohorts. Groups that are never treated should be coded as Zero.
Any positive value indicates which year a group was initially treated. And once a group is treated, the underlying assumption
is that it always remains treated.

e.g., 0 Never treated, 10 treat at t=10, 20 treated at time 20, 25 treated at time 25.

If there are any groups treated before the first available period in the sample, those observations are
considered always treated, and are excluded from the sample.

For every cohort in gvar there should be a period in time otherwise, the command will produce an error. Also, you should have data for the period before treatment. For example, if data is annual, and observations were treated in 2010, you need to have data for this group in 2009. Otherwise ATTGT's cannot be identified.

When using panel data, observations cannot change cohort across time.

notyet Request using observations never treated and those not yet treated as control group.
The default is using never treated only. If there are no never treated observations, notyet is used automatically.

long For periods before treatment, this option requests the estimation of Long gaps, rather
than short-gaps.

long2 For periods before treatment, this option requests the estimation of Long gaps, rather
than short-gaps. This is similar to base universal. (inverse sign from long)

asinr In R's version (DID), pre-treatment ATTGT's using not-yet-treated groups are estimated using all cohorts not-yet treated.
In Stata, the default is to use all cohorts that were not treated at time G. Both options are valid, but if one wants to replicate R results, -asinr- should be used.

Estimation Method

csdid is a generalization of drdid, and as such it allows for various estimators.
It estimates every feasible 2x2 DiD design available in the selected sample.

In all cases, the earliest-period covariates are used for the estimation of the propensity score and outcome regressions. This is the base period for all post treatment ATTGTs and T for all pre-treatment ATTGTs.

To specify a particular syntax, one should use the option method(method) using one of the following key words:

drimp Sant’Anna and Zhao (2020) Improved doubly robust DiD estimator based on
inverse probability of tilting and weighted least squares.

dripw (default) Sant’Anna and Zhao (2020) doubly robust DiD estimator based on stabilized
inverse probability weighting and ordinary least squares.

reg Outcome regression DiD estimator based on ordinary least squares. When no covariates are specified, this
method is used as default, because it provides the same point estimates and standard errors.

stdipw Inverse probability weighting DiD estimator with stabilized weights

ipw Abadie (2005) inverse probability weighting DiD estimator. May not perform well with unbalanced panel data

rc1 In combination with the methods and , this option request the doubly robust
but not locally efficient repeated crossection estimators. Not available when using panel data.

Standard Error Options

By default, robust and asymptotic standard errors are estimated, which are obtained using Influence Functions.
However other options are available.

wboot Request Estimation of Standard errors using a multiplicative WildBootstrap procedure.
The default uses 999 repetitions using mammen approach.

wboot(Options) Request Estimation of Standard errors using a multiplicative WildBootstrap procedure, and allows to change default options

- reps(#) Specifies the number of repetitions to be used for the Estimation of the WBoot SE. Default is 999

- wtype(type) Specifies the type of Wildbootstrap procedure. The default is "mammen", but "rademacher" is also
avilable.

rseed(#) Specifies the seed for the WB procedure. Use for replication purposes.

cluster(clust var) Request the estimation of Clustered Standard errors. This option is valid for asymptotic Standard errors,
and Wbootstrap Standard errors.

Remark 1. When Panel estimators are used, asymptotic and Wbootstrap Standard errors are already clustered at the panel level.
When using cluster, one is effectively requesting a two-way cluster estimation.

Remark 2. When Panel estimators are used, The panel id should be nested within the cluster variable . (ivar)

level(#) Request changing the confidence level (default 95) for the estimation of Confidence Intervals.

pointwise Request producing pointwise CI, when requesting Wildbootstrap SE. The default is to request Uniform Confidence Intervals.

Other Options

saverif(filename) Request the command to save the RIFs for all the DID ATT into a dataset name filename.
It requires a new dataset unless option replace is used.

In addition to the ATT's RIFs, the file also contains the RIFs for the weights that are used for aggregations.

replace In combination with saverif(), requests replacing the file if it already exists

Remark 1: This option can be combined with wildbootstrap standard errors.

Remark 2: This option is used as an alternative to -estimates save-, so you can request other aggregations
or SE after the model has been estimated.

agg(aggtype) This option can be used to produce different aggregations as the command output. The default is
attgt, which produces the ATT for a particular cohort, and a particular period. Other options are:

simple Estimates the ATT for all groups across all periods

group Estimates the ATT for each group or cohort, across all periods

calendar Estimates the ATT for each period, across all groups or cohorts

event Estimates the dynamic ATT's. ATT's are estimated for each period relative to the
period first treated, across all cohorts.

While weights are taken as iweights, weights are treated as pweights internally.

Description

csdid implements the DiD with multiple periods estimator proposed by Callaway and Sant'Anna (2021).

Internally, all 2x2 DiD estimates (ATTGT's) are obtained using -drdid-. Thus csdid works as a wrapper
that determines all relevant designs and aggregates them.

As in -drdid-, the underlying assumption is that all covariates are time constant. When using panel data,
even if covariates are time-varying, only the base-period (earlier-period) values are used for the estimation.

When using crossection data, while all characteristics can be considered time-varying, the underlying assumption is that
within treated and untreated group, characteristics are stationary (time constant). In other words,
be careful of controlling for characteristics that are either time constant (e.g. sex or race), or for
pretreatment characteristics.

The intuition behind Callaway and Sant'Anna (2021) estimator is that in order to obtain consistent estimators for ATT's
one should only use never-treated or not-yet treated units as controls. Otherwise, under heterogeneous treatment effects,
the parallel trends assumption will be violated, and the estimations of the effects could be severely biased.

For the command to work, you need to have at least one period in the data for each group/cohort in gvar. You also require
at least one pre-treatment period for each cohort/group, in order to estimate the ATT for that group.

From the perspective of the treated observations, all ATTGT's are estimated using the last not treated period as "base-period", and
using current period as the post period.

For ATT's before the treatment took place, the command uses T-1 as the base period (or Pre-period), and T as the post-period. This corresponds to the pre-treatment gap.

When long gaps are requested, the ATT's before treatment took place uses T-1 as base period, and G-1 as the post period. where G is the first period a unit received treatment. One can also use , which provides the same estimates but flipped sign. This is the closest to standard event study effects. The usually ommited parameter (T-1) is not calculated with csdid.

For ATT's after the treatment took place, the command uses G-1 as the base period (pre-treatment period) and T as the post-period.

Because the estimator attempts to estimate all ATTGT's for all groups across all periods, the implementation of this estimator
for cross-section data with long time spans and many treated groups may not be feasible. For example, using 30 periods, with 20 potential
groups would require the estimation of 600 separate regressions, and the creation of at least the same number of new variables
containing the RIF's for all ATTGT's, rapidly consuming the memory resources of commonly used computers.

The best advice on these cases is to refine the treatment groups or cohorts, because not all of them may be relevant for your analysis.
Additionally, you may not need ALL periods, requiring only few periods before the first treatment year.

Remarks

When using panel data, the estimator does not require data to be strongly balanced. However, when estimating each ATTGT,
only observations that are balanced within a specific 2x2 designed are used for the estimator. You will see a warning if something like this is detected in the data.

This approach is in contrast with the default approach in R's DID. When unbalanced data exists, the default is to
estimate the model using Repeated Crossection estimators. See the example below contrasting both approaches.

Even if WBootstrap SE are requested, asymptotic SE are stored in e().

Each succesful iteration is represented by a ".", whereas an "x" indicates for some ATT(G,T), the estimation failed.

Post Estimaton

csdid offers three post estimation utilities. See csdid_postestimation for more details.

csdid_estat For the estimation of aggregations and pretreatment tests.

csdid_stats For the estimation of aggregations and pretreatment tests using RIF files.

csdid_plot For the creating plots of the results.

csdid_rif This is a multiuse command. It can be used to produce results, including wildbootstrap tables, based on RIFs.

Examples

use https://friosavila.github.io/playingwithstata/drdid/mpdta.dta, clear

Estimation of all ATTGT's using Doubly Robust IPW (DRIPW) estimation method

csdid lemp lpop , ivar(countyreal) time(year) gvar(first_treat) method(dripw)

Estimation of all ATTGT's using Doubly Robust IPW (DRIPW) estimation method, with Wildbootstrap SE

csdid lemp lpop , ivar(countyreal) time(year) gvar(first_treat) method(dripw) wboot rseed(1)

Repeated crosssection estimator with Wildbootstrap SE

csdid lemp lpop , time(year) gvar(first_treat) method(dripw) wboot rseed(1)

Estimation of all Dynamic effects using Doubly Robust IPW (DRIPW) estimation method, with Wildbootstrap SE

csdid lemp lpop , ivar(countyreal) time(year) gvar(first_treat) method(dripw) wboot rseed(1) agg(event)

Estimation of all Dynamic effects using Doubly Robust IPW (DRIPW) estimation method, with Wildbootstrap SE,
and not-yet treated observations as controls

csdid lemp lpop , ivar(countyreal) time(year) gvar(first_treat) method(dripw) wboot rseed(1) agg(event) notyet

Estimation of ATTGT's assuming unbalance panel data, with panel estimators

set seed 1

gen sample = runiform()<.9

csdid lemp lpop if sample==1, ivar(countyreal) time(year) gvar(first_treat) method(dripw)

Estimation of ATTGT's assuming unbalance panel data, with repeated crosssection estimators, but clustered SE

csdid lemp lpop if sample==1, cluster(countyreal) time(year) gvar(first_treat) method(dripw)

Authors

Fernando Rios-Avila

Levy Economics Institute of Bard College

Annandale-on-Hudson, NY

friosavi@levy.org

Pedro H. C. Sant'Anna

Vanderbilt University

Brantly Callaway

University of Georgia

References

Abadie, Alberto. 2005.
"Semiparametric Difference-in-Differences Estimators."
The Review of Economic Studies 72 (1): 1–19.

Callaway, Brantly and Sant'Anna, Pedro H. C. 2021.
"Difference-in-Differences with multiple time periods." , 225(2):200-230.
Journal of Econometrics.

Sant’Anna, Pedro H. C., and Jun Zhao. 2020.
"Doubly Robust Difference-in-Differences Estimators."
Journal of Econometrics 219 (1): 101–22.

Rios-Avila, Fernando,
Pedro H. C. Sant'Anna,
and Brantly Callaway, 2021.
“CSDID: Difference-in-Differences with Multiple periods.”

Aknowledgement

This command was built using the DID command from R as benchmark, originally written by Pedro Sant'Anna and Brantly Callaway.
Many thanks to Pedro and Brantly Callaway for helping to understand the inner workings of the estimator, .

Thanks to Enrique, who helped with the display set up

If you use this package, please cite:

Callaway, Brantly and Sant'Anna, Pedro H. C. 2021.
"Difference-in-Differences with multiple time periods.",
Journal of Econometrics, 225(2):200-230.

Sant'Anna, Pedro H. C., and Jun Zhao. 2020.
"Doubly Robust Difference-in-Differences Estimators."
Journal of Econometrics 219 (1): 101–22.

Also see

Help: drdid, csdid, csdid postestimation, xtdidregress