Code Call-out 5.1: Treatment Assignment with Imperfect Compliance
In this code call-out we use data of Finkelstein et al. (2012), which analyses the impact of public insurance coverage on a range of health outcomes and measures of well-being. Finkelstein et al. (2012) analyze the Oregon Health Insurance Experiment, which randomly selected by lottery a group of households who could then submit the paperwork to be able to enroll in Medicaid, a public health insurance program which covers individuals’ medical expenses. Medicaid is offered to low income households, and in general individuals covered by Medicaid are different in a range of ways to individuals not covered by Medicaid. But because the Oregon Health Insurance Experiment randomly assigned individuals to a treatment group, which was invited to apply for Medicaid, and a control group, which was not invited to apply for Medicaid, this random assignment can be used as an instrument for Medicaid coverage.
In this code call out we use data from Finkelstein et al. (2012) to estimate the local average treatment effect of Medicaid on health outcomes. In particular, we focus on understanding the range of ways which we can mechanically arrive to this estimand, showing the equivalance between, 2SLS, the Wald estimator, and indirect least squares as laid out in Section 5.2.4 of the book. This should also make clear to us the relationship between the intention to treat effect, the 2SLS first stage and the LATE.
In the file Finkelstein_et_al_2012.csv you can find a minimalist sample of the data used by Finkelstein et al. (2012) in order to replicate some of the paper’s tables 3 and 5 results. This minimalist sample consists of respondents to a survey that was sent out by mail in seven waves between July and August 2009.
In this example we will focus on a binary outcome er_any_12m which takes a value of 1 if individual has any ER visits in last six months and 0 otherwise. The endogenous treatment indicator variable \(D\) is a binary variable ohp_all_ever_survey which takes 1 if the individual was ever on Medicaid during the study period and our instrument \(Z\) is a binary variable treatment which takes 1 if the individual’s household was selected by the lottery. Below, we load these data, rename the outcome, endogenous variable and instrument as Y, D and Z respectively, and make one minor edit to convert our outcome variable to a numeric format. Note that here we are dropping a small number of individuals for whom we do not have information on the outcome of interest:
import delimited "data/Finkelstein_et_al_2012.csv", clearrename (er_any_12m ohp_all_ever_survey treatment) (Y D Z)dropif Y == "NA"destring Y, replace
(encoding automatically selected: ISO-8859-1)
(21 vars, 23,741 obs)
(227 observations deleted)
Y: all characters numeric; replaced as byte
We will begin by estimating Intention to Treat Effect (ITT) of lottery receipt, to see that we can replicate the parameters reported by Finkelstein et al. (2012). To estimate the ITT, we simply estimate: \[Y_i = \beta_0 + \beta_1 Z_i + X^\prime_i\Gamma + \varepsilon_i\] Where \(X_i\) is a vector of covariates which includes indicator variables for the number of individuals in the household listed on the lottery sign-up form, indicator variables for survey wave and the interaction between these two sets of indicator variables. As laid out in Finkelstein et al. (2012), we will cluster standard errors at the household level
reg Y Z ddd* [pw = weight_12m], vce(cluster household_id)
As we see above, this ITT results in an estimate of 0.0065 with a corresponding standard error of 0.0067. This replicates the result of Finkelstein et al. (2012) column 2 of table 5, suggesting that individuals who were randomly assigned to the option to apply to Medicaid – whether or not they ultimately gain access to Medicaid – had slightly higher rates of ER usage, however we cannot rule out that this effect is 0 with at standard levels of confidence.
Manually Estimating 2SLS: Right Estimates, Wrong Standard Errors
If we wish to estimate the LATE itself, there are a number of ways which we can proceed. In practice, we will essentially always want to make use of statistical routines for IV or 2SLS estimation, which will guarantee the correct implementation of standard errors. However, it is perhaps illustrative to see that we can “manually” estimate 2SLS, and—the point estimates at least—will agree entirely with those from 2SLS estimation routines. If we wish to estimate 2SLS, we can (logically) proceed in two stages. Below we begin by estimating the first stage, regressing endogenous treatment receipt on the randomly assigned lottery:
reg D Z ddd* [pw = weight_12m], vce(cluster household_id)
Here we include the same set of controls and weights. We have also clustered standard errors by household, but for this manual implementation of 2SLS, this actually does not matter, as we will be simply working with predicted values \(\widehat{D}_i\) in the second stage, which do not depend on the first stage standard errors (indeed, for this reason, our standard errors in this manual implementation will be wrong!). As we see above, the first stage coefficient for lottery assignment is 0.290, which suggests that being selected by the lottery actually increases the likelihood of being covered by Medicaid by 29.0%. This replicates the results laid out Table 3, column 6. This value is not 1 because various households which were selected did not end up applying for Medicaid, and other households did apply, but ended up not meeting maximum income thresholds. With this first stage estimation in hand, now all we need to do to estimate our 2SLS (LATE) parameter is generate the predicted value \(\widehat{D}_i\), and regress \(Y_i\) on \(\widehat{D}_i\), conditional on the same controls and weights. We do this below:
This results in an estimated LATE of 0.022, and a standard error of 0.023 (see Finkelstein et al. (2012), Table 5, column 3). This suggests that Medicaid receipt results in a small increases in access to the ER, though again we cannot rule out that this estimate is 0 at standard levels of confidence. What we are interested in showing here, however, is that this “manual” 2SLS procedure is precisely what is estimated (thought with the correct standard errors now) if we use formal routines, such as Stata’s ivregress 2sls command:
Above we see that with this procedure we perfectly recovered the same point estimate as above (0.022), but that standard errors is slightly higher. The fact that standard errors are higher makes sense, and indeed such a result will always occur, given that we are now accounting for the fact that the first stage prediction is estimated, and not a known regressor.
2SLS as the Reduced Form Divided by the First Stage: Indirect Least Squares
To understand more deeply what 2SLS is doing, it is also useful to see that we can build this up in a number of alternative ways. One of these is to note that our LATE estimate is simply the ratio of the reduced form (ie the ITT) to the first stage. Because the reduced form captures the effect of random assignment on the outcome of interest, and because the first stage is not actually equal to one, to estimate the effect of Medicaid receipt itself we must “scale up” the reduced form to correct for the fact that only some proportion of individuals assigned to treatment actually received treatment. Below we see this, where we are simply re-estimating two of the quantities we already estimated above (the ITT and the first stage), before finally taking their ratio:
* Estimate ITT and retrieve coefficientquireg Y Z ddd* [pw = weight_12m], vce(cluster household_id)scalar itt = _b[Z]* Estimate first stage and retrieve coefficientreg D Z ddd* [pw = weight_12m], vce(cluster household_id)scalar fs = _b[Z]* Compute Indirect least squaresdi"The Indirect Least Squares estimate is " itt / fs
As we can see, the value estimated by this “indirect least squares” root is precisely the same as that estimated by 2SLS previously.
2SLS, IV and the Wald Estimator: Equivalent in Setting with a Binary IV and no Covariates
Finally, note that in cases where we are working with a binary instruments (as in this case), and if there are no controls, we can arrive to our LATE in a number of other ways including by implementing the Wald Estimator: \[\widehat\tau^{Wald}_{LATE}=\frac{E[Y_i|Z_i=1]-E[Y_i|Z_i=0]}{E[D_i|Z_i=1]-E[D_i|Z_i=0]},\] or by estimating IV: \[\widehat\tau^{IV}_{LATE}=\frac{Cov(Y_i,Z_i)}{Cov(D_i,Z_i)}.\] While these are just equivalent ways of estimating the same thing, it is useful to see, and we will illustrate this below, first estimating 2SLS without any controls or weights:
//Estimate 2SLSivregress 2sls Y (D=Z)dis "The 2sls estimate is:" _b[D]
Instrumental-variables 2SLS regression Number of obs = 23,514
Wald chi2(1) = 0.12
Prob > chi2 = 0.7267
Root MSE = .43605
------------------------------------------------------------------------------
Y | Coefficient Std. err. z P>|z| [95% conf. interval]
-------------+----------------------------------------------------------------
D | -.0067617 .0193471 -0.35 0.727 -.0446812 .0311579
_cons | .2566803 .0061248 41.91 0.000 .2446759 .2686846
------------------------------------------------------------------------------
Endogenous: D
Exogenous: Z
The 2sls estimate is:-.00676169
and then comparing this to the Wald estimate:
//Estimate Waldsum Y if Z==1local YZ1 = r(mean)sum Y if Z==0local YZ0 = r(mean)sum D if Z==1local DZ1 = r(mean)sum D if Z==0local DZ0 = r(mean)dis "The Wald estimate is:" (`YZ1'-`YZ0')/(`DZ1'-`DZ0')
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
Y | 11,691 .253785 .4351946 0 1
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
Y | 11,823 .2557726 .4363131 0 1
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
D | 11,691 .4281926 .494838 0 1
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
D | 11,823 .1342299 .3409136 0 1
The Wald estimate is:-.00676169
and the IV estimate:
//Estimate IVcorr Y Z, covlocal CovYZ = r(cov_12)corr D Z, covlocal CovDZ = r(cov_12)dis "The IV estimate is:" (`CovYZ')/(`CovDZ')
(obs=23,514)
| Y Z
-------------+------------------
Y | .189877
Z | -.000497 .250003
(obs=23,514)
| D Z
-------------+------------------
D | .201778
Z | .073491 .250003
The IV estimate is:-.00676169
These are, as we see above, all exactly equivalent. One could also extend this to a setting with weights if appropriately weighting the statistics in the Wald estimate, though we will leave this as an exercise for you to explore.
Code Call-out 5.2: Characterising Compliers
To understand how Abadie’s Kappa is estimated and how this allows to understand the characteristics of compliers, we use data and setting from Clingingsmith, Khwaja, and Kremer (2009) who study the Hajj pilgrimage to Mecca. We open these data, called Clingingsmith_et_al_2009.csv, below:
In their paper, Clingingsmith, Khwaja, and Kremer (2009) instrument whether an individual made the Hajj pilgrimage in 2006 (hajj2006) with the outcome of a random lottery which determines the awarding of limited Hajj visas. The outcome of this random lottery process (success) strongly affects the likelihood an indivudal makes the pilgrimage, but is not deterministic, as unsuccessful applicants can seek places through private operators. Thus, it can be viewed as a case of random assignment with imperfect compliance. Clingingsmith, Khwaja, and Kremer (2009) use this visa to study how making this pilgrimage shapes beliefs and views of a sample of around 1600 lottery applicans from Pakistan. Here we consider the composition of compliers in terms of a range of covariates, in particular documenting complier means using Abadie’s Kappa. Below we keep our “treatment” of interest and the IV, as well as a number of covariates we will consider later in this call-out.
keep success hajj2006 female age urban literate
For ease of notation below, we will redefine D = hajj2006 and Z = success as our indicater variables for treatment and instrument respectively.
rename (hajj2006 success) (D Z)
Before turning to consider the characteristics of compliers themselves, let’s briefly examine the first stage:
reg D Zdis "Rate of Hajj among individuals who are successful in the visa:"dis _b[Z]+_b[_cons]
Source | SS df MS Number of obs = 1,605
-------------+---------------------------------- F(1, 1603) = 4881.30
Model | 291.712924 1 291.712924 Prob > F = 0.0000
Residual | 95.7973567 1,603 .059761296 R-squared = 0.7528
-------------+---------------------------------- Adj R-squared = 0.7526
Total | 387.51028 1,604 .24158995 Root MSE = .24446
------------------------------------------------------------------------------
D | Coefficient Std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
Z | .8544795 .0122302 69.87 0.000 .8304907 .8784684
_cons | .1373333 .0089265 15.38 0.000 .1198246 .1548421
------------------------------------------------------------------------------
Rate of Hajj among individuals who are successful in the visa:
.99181287
With this simple bivariate regression we can see the three relevant proportions as the rate of individuals who make the pilgrimage when not successful in the lottery (the constant of 0.14), the increase in the likelihood that an individual makes the pilgrimage when being successful in the lotter (the first stage effect of 0.85), and hence the likelihood of making the pilgrimage when being successful in the lottery as the sum of these two terms (0.99). The fact that the first stage is very strong will have an impact on how compliers compare to the entire sample, given that most individuals here are indeed compliers.
Covariate Means
Our main goal in this code call-out is to explore Abadie’s kappa, and how this allows us to “describe” compliers. We will thus be interested in calculating a series of means of covariates among compliers. In particular, we will consider the covariates documeted in Table 2 of Clingingsmith, Khwaja, and Kremer (2009), and for this will create the rural and illiterate variables as the complements of urban and literate respectively.
Now we summarise these variables to ensure that they do indeed coincide with those documented in the paper’s Table 2:
* Matrix to storemeansmatrix stat_df = J(5,2,.)matrixcolnames stat_df = "Full Sample""Compliers"matrixrownames stat_df = "Age""Female""Illiterate""Urban""Rural"* Counter to iterate through matrixrowslocal rowcounter = 0* For each covariateforeach vari ofvarlist age female illiterate urban rural{ * Add one to row counterlocal rowcounter = `rowcounter' + 1 * Summarize variablequisum`vari' * Assign the meanmatrixdefine stat_df[`rowcounter', 1] = r(mean)}* Show matrixmatrixlist stat_df
stat_df[5,2]
Full Sample Compliers
Age 54.575078 .
Female .49034268 .
Illiterate .40186916 .
Urban .6741433 .
Rural .3258567 .
Above we have saved the mean of each variable in a matrix called stat_df, and below we will populate the remaining cells to examine how our complier means correspond to the means in the full sample which we hav egenerated above.
Computing Abadie’s Kappa
In order to calculate mean characteristics of compliers, we start by calculating Abadie’s Kappa using the textbook formula (5.27): \[
\kappa_i = 1 - \frac{D_i (1 - Z_i)}{\Pr(Z_i = 0|X_i)} - \frac{(1 - D_i) Z_i}{\Pr(Z_i = 1|X_i)}
\]
We observe each individual’s treatment status \(D_i\) and instrument \(Z_i\), but we do not observe the conditional probabilities \(\Pr(Z_i = 1|X_i)\) and \(\Pr(Z_i = 0|X_i)\). To estimate them, we fit a probit model of the instrument on covariates:
* Estimate instrument propensity scoreusingprobitquiprobit Z female age urban literate* Predict probabilitiespredict PrZ1, prgen PrZ0 = 1 - PrZ1
We then compute Abadie’s kappa using the estimated probabilities:
* Compute Abadie's kappagen Kappa = 1 - ( ( D * ( 1 - Z ) ) / PrZ0 ) - ( ( ( 1 - D ) * Z ) / PrZ1 )
Let’s now have a look at what this Kappa looks like in our data, with a simple histogram plot:
There are perhaps two key features we notice in this histogram. Firstly, we can see a large mass of units (93.15%) whose value for Abadie’s Kappa is concentrated around the value of 1. This is due to the high compliance level of this study as you can note from formula (5.27) that all compliers will have a value of 1 for their Abadie’s Kappa (as will any individuals who comply with their treatment assignment). Secondly, we note a series of negative values. This is also expected given the nature of the second and third terms in the formula for Abadie’s Kappa. You can see that both of these terms must either have 0 or 1 in the numerator. If \(Z_i=0\) and \(D_i=1\) (always-takers with values of zero for the instrument) the numerator of the first term will be one and of the second term will be 0, whereas if \(D_i=0\) and \(Z_i=1\) (never-takers assigned 1 for the instrument), the numerator of the second term will be 0 and that of the third term will be 1. Finally, note that as the denominator of each of these terms is strictly between 0 and 1, these terms must be bounded between 1 and \(\infty\), meaning that for non-compliers, Abadie’s Kappa will always be negative. In cases where \(\Pr(Z_i=0|X_i)\) and \(\Pr(Z_i=1|X_i)\) are approximately 0.5 (as we see below), we would expect that these second and third terms should be around -2, resulting in values of Abadie’s Kappa around -1.
sum PrZ0 PrZ1
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
PrZ0 | 1,605 .4672846 .0239108 .3937983 .5453299
PrZ1 | 1,605 .5327154 .0239108 .4546701 .6062017
Covariate Means among compliers
Now finally, with our calculated values for Abadie’s Kappa we can estimate the complier means of covariates following the textbook formula (5.28) \[E[x_1|D_1 > D_0] = \frac{1}{\Pr(D_1 > D_0)}E[\kappa x_1]\] Where \(\Pr(D_1 > D_0)\) is the rate of compliance in this sample, which incidentally can be calculated as the expected value of Abadie’s Kappa. We estimate these complier-means below:
*Complier's mean denominatorsum Kappascalar PrD1 = r(mean)* Complier's mean estimatelocal rowcounter = 0foreach vari ofvarlist age female illiterate urban rural{local rowcounter = `rowcounter' + 1quireplace`vari' = `vari' * Kappaquisum`vari'matrixdefine stat_df[`rowcounter', 2] = r(mean) / PrD1}* Show resultsmatrixlist stat_df
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
Kappa | 1,605 .8541775 .5387896 -1.368137 1
stat_df[5,2]
Full Sample Compliers
Age 54.575078 54.887654
Female .49034268 .49541392
Illiterate .40186916 .41566074
Urban .6741433 .66164823
Rural .3258567 .33835177
As you can see the mean of covariates for full sample and compliers are very similar due to the high compliance level of this study, with some minor variations by specific variables.
Code Call-out 5.3: Average Causal Response Functions
To understand how Average Causal Response (ACR) Functions are estimated we use data from Bhalotra and Clarke (2020). Bhalotra and Clarke (2020) is a paper based on the twin instrument, in which the impact of a twin at different birth orders is used to instrument total fertility. This code call-out replicates the baseline scenario in plots (b) and (e) from Panels A and B respectively, in Figure 3 of Bhalotra and Clarke (2020) and Figure 5.2 of the book. We begin by opening the data which pools surveys from the USA and the developing world. These data are rather large, which is important given the relative infrequency of twins, and necessity of a large sample to estimate parameters precisely with IV.
In particular here we focus on a binary IV which records whether a mother gives birth to a twin on her third birth, on total fertility, a categorical variable. In order to understand what this IV identifies, we must estimate the ACR, which computes how the instrument shifts fertility from \(j-1\) to \(j\) children, over the support of \(j\). We thus start by generating indicators for whether an individual gives birth to at least \(j\) children: \(\mathbf{1}\{fert_i \geq j\}\), for values of \(j\in\{1,\ldots,11\}\). We start at 4 births given that our instrument is the occurrence of twins (rather than singleton births) at birth order 3, and so all families must have at least 3 births.
We first focus on data from the developing country sample (based on the DHS), this is Panel A from Figure 3 in Bhalotra and Clarke (2020).
keepif datasource == "DHS"
(227,213 observations deleted)
To estimate the ACR functions, we estimate the following regressions: \[
\mathbf{1}\{\text{Fert}_i = k\} = \beta_0 + \beta_1 \mathbf{1}\{\text{TwinBirth}_i = 3\} + \mathbf{X}'\gamma + \varepsilon_i
\tag{1}\]
where \(\mathbf{1}\{\text{Twin Birth} = 3\}\) is a dummy variable equal to 1 if family \(i\) had a twin birth at the third parity (twin_three_fam), and \(\mathbf{X}\) is a vector of control variables. These include: A dummy for male child (malec), Dummies for country of origin (_cou), Mother’s year of birth (year_birth), The child’s age in years (age), Contraceptive use and intentions (contracep_intent), Child’s birth order (bord, omitting bord == 1), Mother’s age at the child’s birth (motherage), Mother’s age at first birth (agefirstbirth). These controls are important given the argument that twins are at best random conditional upon maternal age and health. Given the survey weights in DHS, we estimate the model using weighted least squares, applying sampling weights (sweight), and clustering standard errors at the family level (id). The analysis is restricted to families with at least three births (three_plus). We begin by generating a number of required variables below, and sub-setting to our estimation sample.
* Country codeencode _cou, generate(num_cou)* Contraceptive intent codeencode contracep_intent, generate(num_contracep_intent)* Keep families with 3+ childskeepif three_plus == 1
(2,821,061 observations deleted)
The ACR requires estimating Equation 1 for each fertility indicator, in essence allowing us to map out how the instrument shifts the likelihood that individuals exceed all points of the distribution of the endogenous variable. As we wish to plot each of the coefficients and confidence intervals from this model we will create a matrix to store these below, and then progressively fill them in as we estimate models.
matrix ACR = J(8, 5, .)
Now, with this all in hand, we can loop through the support of the fertility variable, estimating Equation 1 for \(j \in \{4, 5, \ldots, 11\}\) and storing the results.
This results in a series of 8 estimates (and indeed, we could continue beyond 11 or more births, but there are very few births at such a high parity, and these are unlikely to be substantially affected by twins at birth order 3). It is standard to plot this ACR across the support of the “treatment” variable of interest, and we do this below, first saving the estimates stored in the matrix ACR into memory, and then generating the plot of interest.
// Assign to datasvmat ACR// Rename variablesrename (ACR1 ACR2 ACR3 ACR4 ACR5) (Childs_plus Point SE LB UB)// Generate Plottwowayscatter Point Childs_plus, mcolor(black) /// || line Point Childs_plus, lcolor(blue) /// || rcap UB LB Childs_plus, lcolor(black) ///scheme(plottig) yline(0, lcolor(red) lpattern(dash)) ytitle("Estimate") ///xtitle("Number of Children") ylabel(, angle(0)) ///xlabel(4 "4+" 5 "5+" 6 "6+" 7 "7+" 8 "8+" 9 "9+" 10 "10+" 11 "11+") ///legend(off)
ACR Function for Developing Countries
We observe here that, perhaps as we may expect, twins at birth order 3 generally shifts fertility low in distribution. Indeed, the largest shift observed occurs among families who in the absence of twins would have had 3 children, but now have four children. We then observe lower shifts at higher birth orders. In this sample, this provides us a clear illustration of how we should understand the LATE in terms of the categorical fertility variable.
However, such an ACR is of course specific to the sample and the setting of interest. Let’s repeat the process above, however now using the sample of data from the USA. Below, we will essentially follow the identical procedures as those documented above and so do not step this through line-by-line, but do note that given the data used in the USA (the National Health Interview Survey) is different to that used above, the controls are slightly different. Specically, below we control for the mother’s age at first birth (ageFirstBirth), dummies for the mother’s age at date of birth of the child (motherAge), dummies for the survey year (Syear), dummies for the age of interview (Bdate), dummies for the region (region), dummies for the mother’s race (mrace) and the child’s sex (childSex). Everything else is identical to the procedures documented above.
// Import datasetimport delimited "data/Bhalotra_Clarke_2020.csv", clear// Gen dummies for at least j childrenforvalues j = 4/11 {gen fert`j' = (fert >= `j') & (fert != .) }// Keep USA datakeepif datasource == "NHIS"// Keep if has at least three childskeepif three_plus == 1// Matrix to store resultsmatrix ACR = J(8, 5, .)local FEs motherage surveyyear ageinterview region motherrace childsex// Estimatesforvalues j = 4/11 {qui reghdfe fert`j' twin_three_fam agefirstbirth [pw = sweight], absorb(`FEs') vce(cluster mid)matrixdefine ACR[`j'-3, 1] = `j'matrixdefine ACR[`j'-3, 2] = _b[twin_three_fam]matrixdefine ACR[`j'-3, 3] = _se[twin_three_fam]matrixdefine ACR[`j'-3, 4] = _b[twin_three_fam] + invnormal(0.025) * _se[twin_three_fam]matrixdefine ACR[`j'-3, 5] = _b[twin_three_fam] + invnormal(0.975) * _se[twin_three_fam]}// Assign to datasvmat ACR // Rename variablesrename (ACR1 ACR2 ACR3 ACR4 ACR5) (Childs_plus Point SE LB UB)// Plot resultstwowayscatter Point Childs_plus, mcolor(black) /// || line Point Childs_plus, lcolor(blue) /// || rcap UB LB Childs_plus, lcolor(black) ///scheme(plottig) yline(0, lcolor(red) lpattern(dash)) ytitle("Estimate") ///xtitle("Number of Children") ylabel(, angle(0)) ///xlabel(4 "4+" 5 "5+" 6 "6+" 7 "7+" 8 "8+" 9 "9+" 10 "10+" 11 "11+") ///legend(off)
If we inspect the output in this case, it is immediately apparent that despite being based on the same empirical design and the same instrument, the ACR in the USA is very different to that in the developing country sample. While this makes contextual sense: in general fertility is lower and there is greater access to contraceptive methods, methodlogically perhaps the key point is that it is very important to consider what underlying variations generated by instrumental assignment imply for resulting treatment effects. In the developing country case and the US-case, one explanation of different estimates if the entire IV set-up was estimated is that we are simply exploring very different movements in the treatment variable in both cases.
Code Call-out 5.4: Fully Saturating a Model with Controls
In this code call out we will explore the concept of ‘fully saturating’ an IV model where covariates are required, as well as seeing that this fully saturated model captures underlying covariate-specific LATEs weighted by the relative explanatory power of the first state in each case. To see this, we will work with data from Duflo, Kiessel, and Lucas (2024). They study the impact of a number of school-level interventions in Ghana on child test scores. While the interventions themselves were randomly assigned, take-up was imperfect, and hence random assignment can be used to instrument take-up and estimate a LATE. We will focus on one specific outcome which is student scores on “foundational questions” in academic year 2, and we will examine the impact of receiving any intervention. This corresponds to column 3 of table 3 in Duflo, Kiessel, and Lucas (2024). To begin, we will open the original student-level data from the paper, and keep only students scores in year 2:
We start by simply estimating an IV model with controls to replicate the results from column 3 of Table 3. Here, we regress test scores (e2_engmath_ASER_theta) on an indicator of how frequently schools were observed to be correctly implementing interventions (tarl) instrumented by random assignment to treatment (anytreat). We control for an indicator of whether the student is female, as well as full strata fixed effects.
One thing to note is that the above specification is not actually ‘fully saturated’. For a model to be fully saturated we must both include all possible combinations of controls, and also include a separate interaction of each covariate level with the instrument. To see this in a simple set-up, we can first imagine that we had just a single covariate in our model. Later, we will see how things generalise for a setting with additional controls. We do this below with the binary indicator female. Here, because there are only two possible levels of controls, we need to generate an interaction with each level of the covariate to generate our fully saturated first stage. We do this below generating an interaction between the instrument for females (Z1) and males (Z2):
gen Z1 = anytreat*femalegen Z2 = anytreat*(1-female)
Now, let’s have a look at the “weight and saturate” idea in practice. To begin then, we will estimate the fully-saturated model. Note that here we must include the instrument for each level of female in the first stage which we generated above, and also control for all levels of the variables themselves. Given that female is a binary variable (and that we must omit a baseline reference group), this simply consists of including the covariate female below:
The specification above is our fully saturated model, and we store the resulting esimate as a local IV2SLS to consult below. Now, let’s confirm that this is equivalent to the weighted average of covariate-specific LATEs. To begin, we will calculate each LATE (one for female==1, and one for female==0), and store these as their own quantity:
ivregress 2sls e2_engmath_ASER_theta (tarl=anytreat) if female==1, cluster(schcode)local IV1 = _b[tarl]ivregress 2sls e2_engmath_ASER_theta (tarl=anytreat) if female==0, cluster(schcode)local IV2 = _b[tarl]
Then, we can calculate the weights themselves. Note that to do this we want to calculate the variance of the first stage prediction. So, below we calculate the first stage prediction as Dhat, and then calculate the variance for each first stage, which is also stored in a local:
reg tarl Z1 Z2 femalepredict Dhatsum Dhat if female==1local V1 = r(Var)sum Dhat if female==0local V2 = r(Var)
Source | SS df MS Number of obs = 28,356
-------------+---------------------------------- F(3, 28352) = 1603.32
Model | 305.564566 3 101.854855 Prob > F = 0.0000
Residual | 1801.12636 28,352 .063527313 R-squared = 0.1450
-------------+---------------------------------- Adj R-squared = 0.1450
Total | 2106.69093 28,355 .074296982 Root MSE = .25205
------------------------------------------------------------------------------
tarl | Coefficient Std. err. t P>|t| [95% conf. interval]
-------------+----------------------------------------------------------------
Z1 | .2635252 .0054415 48.43 0.000 .2528597 .2741908
Z2 | .2613498 .0052644 49.64 0.000 .2510313 .2716683
female | 9.60e-14 .006795 0.00 1.000 -.0133186 .0133186
_cons | -1.65e-14 .0047354 -0.00 1.000 -.0092816 .0092816
------------------------------------------------------------------------------
(option xb assumed; fitted values)
(1,075 missing values generated)
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
Dhat | 13,514 .2113623 .1050052 7.95e-14 .2635252
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
Dhat | 14,842 .2114641 .102712 -1.65e-14 .2613498
Finally, we can follow equation 5.42 in the book, and generate the weights based on the variances above and the frequency of each covariate group in data:
Variable | Obs Mean Std. dev. Min Max
-------------+---------------------------------------------------------
female | 28,356 .4765834 .4994602 0 1
Now, finally, let’s just confirm that our weighted group-specific LATE quantity does indeed return approximately the same value as the saturated first stage model:
local IVweighted = `IV1'*`omega1' + `IV2'*`omega2'dis "Original 2SLS is "string(`IV2SLS', "%9.5f")dis "Weighted IV is "string(`IVweighted', "%9.5f")
Original 2SLS is 0.23568
Weighted IV is 0.23568
We see that here (as expected) our estimates do indeed coincide. Note that because these are asymptotically equivalent, in finite samples we may observe minor variations in the calculated estimates in each case, but as the sample grows, we will see that these quantities converge.
While this is all relatively clear with a single covariate (with a single level), things get a little bit more complex if there are multiple covariates and multiple levels. Because we need fully saturated covariates, we need a single covariate for each possible combination of \(X_i\) in data (ie we need the design matrix). In this particular case where we have 40 strata indicators (which are fortunately mutually exclusive), as well as a binary female indicator, we need up to 80 different instruments in the first stage, as well as a variable for each covariate. We will see that while this is a bit cumbersome in terms of output, we can also do this here.
We set this up below by looping through all possible combinations of covariate levels that can be observed in data. We do this by generating an indicator for each strata and female or male indicator (as a series of variables X1, X2, …), and then also a series of instruments for each of these as Z1, Z2, … Because there are a number of small strata in the data, we also confirm that the instrument does indeed vary for all covariate combinations, and if it does now, we simply remove these covariates and instruments from our data.
drop Z1 Z2 Dhatlevelsofstrata, local(stratvals)local i = 1foreachsoflocal stratvals {foreachwof numlist 0 1 {gen X`i' = strata==`s'&female==`w'gen Z`i' = X`i'*anytreat// Confirm variation of Z within this covariate levelquisum anytreat if X`i'==1ifr(sd)==0 drop X`i' Z`i'local ++i }}// Drop a number of variables where there is no variation in endogenous variable by IVdrop X33 Z33 X34 Z34
Now, having in essence “fully saturated” our data, we can run our IV model with the many controls and first stage instrument interactions. We do this below, saving our 2SLS estimate to compare to the weighted aggregate below.
As in the case with a single control, we can confirm that this is equivalent to the weighted aggregate of covariate-specific LATEs. First, let’s estimate the late for each covariate level in the data. We do this quietly below because this will result in a lot of LATEs!
Now, let’s calculate the inputs for weights for each covariate-specific estimate. It is worth looking through this code carefully to ensure that these elements will allow us to calculate the weights required, as described in equation 5.42 in the book.
// Calculate predicted value of first stage reg tarl Z* X* predict Dhat// Calculate elements for weight of each group, as well as the sum of all weightslocal Vtot = 0foreachvarofvarlist X* {quisum Dhat if`var'==1local V`var' = r(Var)quisum`var'local P`var' = r(mean)local Vtot = `Vtot' + `P`var''*`V`var''}
Finally, we can use the inputs above to estimate the weights, as well as the “saturated and weighted” equivalte of the 2SLS estimate we generated previously. Note that because there are many LATEs, we are just doing this in a loop where we sum iteratively across each covariate level. In this way we sum across all LATEs to arrive to our final IV estimate, and also confirm that we are correctly generating weights by ensuring that weights sum to 1.
local IVweight = 0local omega = 0foreachvarofvarlist X* {local omega`var' = `P`var''*`V`var''/`Vtot'local omega = `omega'+`omega`var''local IVweight = `IVweight' + `IV`var''*`omega`var''}dis "Confirming weights: "string(`omega', "%9.5f")dis "Original 2SLS is "string(`IV2SLS', "%9.5f")dis "Weighted IV is "string(`IVweight', "%9.5f")
Confirming weights: 1.00000
Original 2SLS is 0.21842
Weighted IV is 0.21874
Above we can see that while these is some minor variation between the original 2SLS estimate and the weighted and saturated IV, this is minor, owing to the fact that certain groups are quite small. Asymptotically, these quantities will converge to the same values.
References
Bhalotra, Sonia, and Damian Clarke. 2020. “The Twin Instrument: Fertility and Human Capital Investment.”Journal of the European Economic Association 18 (6): 3090–3139. https://doi.org/10.1093/jeea/jvz058.
Clingingsmith, David, Asim Ijaz Khwaja, and Michael Kremer. 2009. “Estimating the impact of the Hajj: Religion and tolerance in Islam’s global gathering.”The Quarterly Journal of Economics 124: 1133–70.
Duflo, Annie, Jessica Kiessel, and Adrienne M Lucas. 2024. “Experimental Evidence on Four Policies to Increase Learning at Scale.”The Economic Journal 134 (661): 1985–2008. https://doi.org/10.1093/ej/ueae003.
Finkelstein, Amy, Sarah Taubman, Bill Wright, Mira Bernstein, Jonathan Gruber, Joseph P. Newhouse, Heidi Allen, Katherine Baicker, and Oregon Health Study Group. 2012. “The Oregon Health Insurance Experiment: Evidence from the First Year.”The Quarterly Journal of Economics 127 (3): 1057–1106. https://doi.org/10.1093/qje/qjs020.