# did2s_stata **Repository Path**: econometric/did2s_stata ## Basic Information - **Project Name**: did2s_stata - **Description**: did2s_stata - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-03-12 - **Last Updated**: 2025-10-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # did2s The goal of did2s is to estimate TWFE models without running into the problem caused by staggered treatment adoption. For details on the methodology, view this [vignette](http://kylebutts.com/did2s/articles/Two-Stage-Difference-in-Differences.html) > [!WARNING] > > Due to the way Stata handles the `predict` command, users of this > package should be careful when they have always-treated units in their > data or if all units end up treated before the end of the panel. If > any value of `i.unit` or `i.year` are not estimated, then predict will > estimate them as 0s which can predict very weird results. ## Installation You can install did2s from github with: ``` stata net install did2s, replace from("https://raw.githubusercontent.com/kylebutts/did2s_stata/main/ado/") * ssc install did2s ``` ## Two-stage Difference-in-differences (Gardner 2021) I have created an Stata package with the help of John Gardner to estimate the two-stage procedure. The command is `did2s` which estimates the two-stage did procedure. This function requires the following syntax `did2s depvar [if] [in] [weight], first_stage(varlist) second_stage(varlist) treatment(varname) cluster(varname)` - `first_stage`: formula for first stage, can include fixed effects and covariates, but do not include treatment variable(s)! - `second_stage`: List of treatment variables. This could be, for example a 0/1 treatment dummy, a set of event-study leads/lags, or a continuous treatment variable - `treatment`: This has to be the 0/1 treatment variable that marks when treatment turns on for a unit. If you suspect anticipation, see note above for accounting for this. - `cluster`: Which variable to cluster on. To view the documentation, type `help did2s` into the console. ## Example Usage ``` stata ******************************************************************************** * Static ******************************************************************************** use data/df_het.dta *-> two-stage manually (note standard errors are off) * First-stage regression qui reg dep_var i.state i.year if treat == 0 * y_{it} - \hat{y}_{it}(\infty) qui predict adj, residuals * Second-stage regression reg adj i.treat, cluster(state) nocons Linear regression Number of obs = 31,000 F(1, 39) = 2803.10 Prob > F = 0.0000 R-squared = 0.3776 Root MSE = 1.7505 (Std. err. adjusted for 40 clusters in state) ------------------------------------------------------------------------------ | Robust adj | Coefficient std. err. t P>|t| [95% conf. interval] -------------+---------------------------------------------------------------- 1.treat | 2.380156 .0449558 52.94 0.000 2.289224 2.471087 ------------------------------------------------------------------------------ ``` ``` stata *-> With did2s standard error correction did2s dep_var, first_stage(i.state i.year) second_stage(i.treat) treatment(treat) cluster(state) (Std. err. adjusted for clustering on state) ------------------------------------------------------------------------------ | Coefficient Std. err. z P>|z| [95% conf. interval] -------------+---------------------------------------------------------------- 1.treat | 2.380156 .0614383 38.74 0.000 2.259739 2.500573 ------------------------------------------------------------------------------ ``` You can also do event-study by changing the `second_stage` ``` stata ******************************************************************************** * Dynamic ******************************************************************************** * can not have negatives in factor variable qui gen rel_year_shift = rel_year + 20 qui replace rel_year_shift = 100 if rel_year_shift == . did2s dep_var, first_stage(i.state i.year) second_stage(ib100.rel_year_shift) treatment(treat) cluster(state) (Std. err. adjusted for clustering on state) -------------------------------------------------------------------------------- | Coefficient Std. err. z P>|z| [95% conf. interval] ---------------+---------------------------------------------------------------- rel_year_shift | 0 | .049467 .0795074 0.62 0.534 -.1063647 .2052986 1 | .1550051 .0793407 1.95 0.051 -.0004999 .31051 2 | .0429258 .0861871 0.50 0.618 -.1259978 .2118494 3 | .0798003 .0804802 0.99 0.321 -.0779379 .2375386 4 | .1023325 .0882446 1.16 0.246 -.0706237 .2752886 5 | .2164395 .0947508 2.28 0.022 .0307313 .4021477 6 | .1707938 .083863 2.04 0.042 .0064253 .3351622 7 | .0939678 .0805816 1.17 0.244 -.0639692 .2519048 8 | .089857 .0839759 1.07 0.285 -.0747327 .2544467 9 | .1976289 .0799969 2.47 0.013 .0408378 .35442 10 | .0952583 .0619518 1.54 0.124 -.0261651 .2166817 11 | .0512636 .0586073 0.87 0.382 -.0636046 .1661318 12 | .0877603 .0403517 2.17 0.030 .0086725 .1668482 13 | .1542402 .0439602 3.51 0.000 .0680799 .2404006 14 | .0220904 .0509833 0.43 0.665 -.0778349 .1220158 15 | .035128 .0489484 0.72 0.473 -.0608091 .1310651 16 | -.0508368 .0504833 -1.01 0.314 -.1497822 .0481087 17 | -.0094032 .0495642 -0.19 0.850 -.1065472 .0877408 18 | .0088808 .0564702 0.16 0.875 -.1017987 .1195602 19 | .1179048 .0515519 2.29 0.022 .016865 .2189447 20 | 1.726992 .0826976 20.88 0.000 1.564907 1.889076 21 | 1.752138 .0798351 21.95 0.000 1.595664 1.908612 22 | 1.871223 .0929743 20.13 0.000 1.688997 2.053449 23 | 1.918305 .0755331 25.40 0.000 1.770263 2.066347 24 | 1.939803 .0841477 23.05 0.000 1.774876 2.104729 25 | 2.145797 .0846879 25.34 0.000 1.979812 2.311782 26 | 2.180307 .0920339 23.69 0.000 1.999923 2.36069 27 | 2.347555 .0818049 28.70 0.000 2.18722 2.507889 28 | 2.412952 .0764437 31.57 0.000 2.263125 2.562779 29 | 2.619597 .1075448 24.36 0.000 2.408813 2.830381 30 | 2.680793 .0954052 28.10 0.000 2.493802 2.867784 31 | 2.712427 .120355 22.54 0.000 2.476536 2.948319 32 | 2.671961 .1533243 17.43 0.000 2.371451 2.972471 33 | 2.65589 .1224654 21.69 0.000 2.415862 2.895917 34 | 2.754846 .1293217 21.30 0.000 2.50138 3.008312 35 | 2.823183 .1341382 21.05 0.000 2.560277 3.086089 36 | 2.694037 .1199969 22.45 0.000 2.458847 2.929226 37 | 2.896575 .1265512 22.89 0.000 2.648539 3.14461 38 | 3.130081 .1160177 26.98 0.000 2.902691 3.357472 39 | 3.23066 .1235224 26.15 0.000 2.98856 3.472759 40 | 3.308015 .1120092 29.53 0.000 3.088481 3.527549 -------------------------------------------------------------------------------- ``` This method works with exogenous time-varying covariates as well! ``` stata ******************************************************************************** * Castle Doctrine ******************************************************************************** use https://github.com/scunning1975/mixtape/raw/master/castle.dta, clear * Define Covariates global demo blackm_15_24 whitem_15_24 blackm_25_44 whitem_25_44 * No Covariates did2s l_homicide [aweight=popwt], first_stage(i.sid i.year) second_stage(i.post) treatment(post) cluster(sid) * Covariates did2s l_homicide [aweight=popwt], first_stage(i.sid i.year $demo) second_stage(i.post) treatment(post) cluster(sid) (Std. err. adjusted for clustering on sid) ------------------------------------------------------------------------------ | Coefficient Std. err. z P>|z| [95% conf. interval] -------------+---------------------------------------------------------------- 1.post | .0751416 .0353795 2.12 0.034 .0057991 .1444842 ------------------------------------------------------------------------------ (Std. err. adjusted for clustering on sid) ------------------------------------------------------------------------------ | Coefficient Std. err. z P>|z| [95% conf. interval] -------------+---------------------------------------------------------------- 1.post | .0760161 .0324715 2.34 0.019 .0123731 .1396591 ------------------------------------------------------------------------------ ``` ### Large Datasets or Many Fixed Effects There are some situations where standard errors can not be calculate analytically in memory. The reason for this is that the analytic standard errors require the creation of the matrix containing all the fixed effects used in estimation. When there are a lot of observations and/or many fixed effects, this matrix can’t be stored in memory. In this case, it’s possible to obtain standard errors via bootstrapping a custom program. Here is an example for the example data. You could spend time to make the command more programmable with args, but I find it easier to just write the estimation out. ``` stata use data/df_het.dta, clear egen unique_id = group(state unit) capture program drop did2s_est program did2s_est, rclass version 13.0 regress dep_var i.new_id i.year if treat == 0 tempvar dep_var_resid predict `dep_var_resid', residuals regress `dep_var_resid' ib0.treat, nocons end xtset unique_id year sort unique_id year bootstrap, cluster(state) idcluster(new_id) group(unique_id) reps(100): did2s_est Panel variable: unique_id (strongly balanced) Time variable: year, 1990 to 2020 Delta: 1 unit (running did2s_est on estimation sample) Bootstrap replications (100): .........10.........20.........30.........40.........50.........60.... > .....70.........80.........90.........100 done Linear regression Number of obs = 31,000 Replications = 100 Wald chi2(1) = 1568.60 Prob > chi2 = 0.0000 R-squared = 0.3776 Adj R-squared = 0.3776 Root MSE = 1.7505 (Replications based on 40 clusters in state) ------------------------------------------------------------------------------ | Observed Bootstrap Normal-based __000001 | coefficient std. err. z P>|z| [95% conf. interval] -------------+---------------------------------------------------------------- 1.treat | 2.380156 .0600965 39.61 0.000 2.262369 2.497943 ------------------------------------------------------------------------------ ``` ## References