Chapter 5

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", clear
rename (er_any_12m ohp_all_ever_survey treatment) (Y D Z)
drop if 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)
(sum of wgt is 28,909.5595551729)

Linear regression                               Number of obs     =     23,514
                                                F(17, 20809)      =     368.85
                                                Prob > F          =     0.0000
                                                R-squared         =     0.0064
                                                Root MSE          =     .43784

                      (Std. err. adjusted for 20,810 clusters in household_id)
------------------------------------------------------------------------------
             |               Robust
           Y | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
           Z |   .0064751   .0067203     0.96   0.335    -.0066971    .0196474
ddddraw_su~2 |   .0001359   .0171202     0.01   0.994    -.0334211    .0336928
ddddraw_su~3 |   .0019066   .0173922     0.11   0.913    -.0321835    .0359967
ddddraw_su~4 |  -.0009213   .0162506    -0.06   0.955    -.0327738    .0309312
ddddraw_su~5 |   .0253775    .016569     1.53   0.126    -.0070991     .057854
ddddraw_su~6 |   .0091721   .0150991     0.61   0.544    -.0204234    .0387676
ddddraw_su~7 |   .0100415    .014642     0.69   0.493     -.018658     .038741
dddnumhh_l~2 |  -.0543484   .0198821    -2.73   0.006    -.0933189   -.0153779
dddnumhh_l~3 |  -.0244529   .1235803    -0.20   0.843    -.2666799    .2177741
ddddraxn~2_2 |  -.0049202   .0283877    -0.17   0.862    -.0605623    .0507218
ddddraxn~2_3 |  -.0316792   .1650272    -0.19   0.848    -.3551455     .291787
ddddraxn~3_2 |  -.0121266   .0279279    -0.43   0.664    -.0668674    .0426141
ddddraxn~3_3 |  -.2553663   .1242095    -2.06   0.040    -.4988266    -.011906
ddddraxn~4_2 |  -.0298712   .0262893    -1.14   0.256    -.0814003    .0216578
ddddraxn~5_2 |  -.0342518   .0270943    -1.26   0.206    -.0873587    .0188551
ddddraxn~6_2 |  -.0223769   .0248024    -0.90   0.367    -.0709916    .0262377
ddddraxn~7_2 |  -.0089282   .0468559    -0.19   0.849    -.1007693     .082913
       _cons |   .2719892   .0127177    21.39   0.000     .2470615    .2969169
------------------------------------------------------------------------------

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)
(sum of wgt is 28,909.5595551729)

Linear regression                               Number of obs     =     23,514
                                                F(17, 20809)      =     125.61
                                                Prob > F          =     0.0000
                                                R-squared         =     0.1092
                                                Root MSE          =     .42414

                      (Std. err. adjusted for 20,810 clusters in household_id)
------------------------------------------------------------------------------
             |               Robust
           D | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
           Z |   .2899314   .0066785    43.41   0.000     .2768411    .3030217
ddddraw_su~2 |  -.0458972   .0170392    -2.69   0.007    -.0792954   -.0124991
ddddraw_su~3 |   -.049708   .0174966    -2.84   0.005    -.0840027   -.0154133
ddddraw_su~4 |  -.0636485   .0158866    -4.01   0.000    -.0947874   -.0325095
ddddraw_su~5 |  -.0682771   .0158315    -4.31   0.000     -.099308   -.0372461
ddddraw_su~6 |  -.0636407   .0148206    -4.29   0.000    -.0926902   -.0345912
ddddraw_su~7 |   -.077627   .0142663    -5.44   0.000    -.1055899    -.049664
dddnumhh_l~2 |  -.1113067   .0214158    -5.20   0.000    -.1532834   -.0693299
dddnumhh_l~3 |  -.0126071   .1172338    -0.11   0.914    -.2423945    .2171803
ddddraxn~2_2 |   .0356131   .0303819     1.17   0.241    -.0239377    .0951639
ddddraxn~2_3 |  -.1630362    .155808    -1.05   0.295     -.468432    .1423596
ddddraxn~3_2 |   .0585528   .0315021     1.86   0.063    -.0031938    .1202993
ddddraxn~3_3 |  -.0859646   .2175038    -0.40   0.693     -.512289    .3403598
ddddraxn~4_2 |   .0740766   .0289888     2.56   0.011     .0172563    .1308969
ddddraxn~5_2 |   .0599303   .0285146     2.10   0.036     .0040395    .1158211
ddddraxn~6_2 |   .0639389   .0262383     2.44   0.015     .0125097    .1153681
ddddraxn~7_2 |   .0772291   .0460712     1.68   0.094     -.013074    .1675323
       _cons |   .2088795   .0125937    16.59   0.000     .1841949    .2335642
------------------------------------------------------------------------------

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:

predict D_hat, xb
reg Y D_hat ddd* [pw = weight_12m], vce(cluster household_id)
(sum of wgt is 28,909.5595551729)

Linear regression                               Number of obs     =     23,514
                                                F(17, 20809)      =     368.85
                                                Prob > F          =     0.0000
                                                R-squared         =     0.0064
                                                Root MSE          =     .43784

                      (Std. err. adjusted for 20,810 clusters in household_id)
------------------------------------------------------------------------------
             |               Robust
           Y | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
       D_hat |   .0223333   .0231789     0.96   0.335    -.0230991    .0677658
ddddraw_su~2 |   .0011609   .0171513     0.07   0.946    -.0324569    .0347788
ddddraw_su~3 |   .0030167   .0174231     0.17   0.863    -.0311338    .0371673
ddddraw_su~4 |   .0005002   .0164021     0.03   0.976    -.0316493    .0326497
ddddraw_su~5 |   .0269023   .0167382     1.61   0.108    -.0059058    .0597104
ddddraw_su~6 |   .0105934    .015273     0.69   0.488    -.0193429    .0405297
ddddraw_su~7 |   .0117752   .0149611     0.79   0.431    -.0175498    .0411001
dddnumhh_l~2 |  -.0518625    .019912    -2.60   0.009    -.0908916   -.0128334
dddnumhh_l~3 |  -.0241713   .1235777    -0.20   0.845    -.2663933    .2180506
ddddraxn~2_2 |  -.0057156   .0283901    -0.20   0.840    -.0613624    .0499313
ddddraxn~2_3 |  -.0280381   .1650606    -0.17   0.865    -.3515697    .2954935
ddddraxn~3_2 |  -.0134343   .0279272    -0.48   0.630    -.0681739    .0413052
ddddraxn~3_3 |  -.2534464   .1242123    -2.04   0.041    -.4969121   -.0099806
ddddraxn~4_2 |  -.0315256   .0262962    -1.20   0.231    -.0830682    .0200169
ddddraxn~5_2 |  -.0355903   .0270879    -1.31   0.189    -.0886846     .017504
ddddraxn~6_2 |  -.0238049   .0247499    -0.96   0.336    -.0723166    .0247068
ddddraxn~7_2 |   -.010653   .0468524    -0.23   0.820    -.1024873    .0811813
       _cons |   .2673242   .0149573    17.87   0.000     .2380068    .2966416
------------------------------------------------------------------------------

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:

ivregress 2sls Y ddd* (D = Z) [pw = weight_12m], vce(cluster household_id)
(sum of wgt is   2.8910e+04)

Instrumental-variables 2SLS regression            Number of obs   =     23,514
                                                  Wald chi2(17)   =    2511.78
                                                  Prob > chi2     =     0.0000
                                                  R-squared       =     0.0101
                                                  Root MSE        =     .43687

                      (Std. err. adjusted for 20,810 clusters in household_id)
------------------------------------------------------------------------------
             |               Robust
           Y | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
           D |   .0223333   .0231258     0.97   0.334    -.0229923     .067659
ddddraw_su~2 |   .0011609   .0171144     0.07   0.946    -.0323828    .0347046
ddddraw_su~3 |   .0030167   .0173766     0.17   0.862    -.0310408    .0370742
ddddraw_su~4 |   .0005002   .0163739     0.03   0.976    -.0315921    .0325924
ddddraw_su~5 |   .0269023   .0167012     1.61   0.107    -.0058315    .0596361
ddddraw_su~6 |   .0105934   .0152312     0.70   0.487    -.0192593    .0404461
ddddraw_su~7 |   .0117752   .0149237     0.79   0.430    -.0174747     .041025
dddnumhh_l~2 |  -.0518625   .0198653    -2.61   0.009    -.0907978   -.0129272
dddnumhh_l~3 |  -.0241713   .1239447    -0.20   0.845    -.2670984    .2187558
ddddraxn~2_2 |  -.0057156   .0283471    -0.20   0.840    -.0612749    .0498438
ddddraxn~2_3 |  -.0280381   .1653542    -0.17   0.865    -.3521264    .2960502
ddddraxn~3_2 |  -.0134343   .0278569    -0.48   0.630    -.0680328    .0411642
ddddraxn~3_3 |  -.2534464   .1246427    -2.03   0.042    -.4977417   -.0091511
ddddraxn~4_2 |  -.0315256   .0262389    -1.20   0.230    -.0829529    .0199017
ddddraxn~5_2 |  -.0355903    .027022    -1.32   0.188    -.0885525     .017372
ddddraxn~6_2 |  -.0238049   .0246861    -0.96   0.335    -.0721887    .0245789
ddddraxn~7_2 |   -.010653   .0466261    -0.23   0.819    -.1020384    .0807325
       _cons |   .2673242   .0149193    17.92   0.000      .238083    .2965654
------------------------------------------------------------------------------
Endogenous: D
Exogenous:  ddddraw_sur_2 ddddraw_sur_3 ddddraw_sur_4 ddddraw_sur_5
            ddddraw_sur_6 ddddraw_sur_7 dddnumhh_li_2 dddnumhh_li_3
            ddddraxnum_2_2 ddddraxnum_2_3 ddddraxnum_3_2 ddddraxnum_3_3
            ddddraxnum_4_2 ddddraxnum_5_2 ddddraxnum_6_2 ddddraxnum_7_2 Z

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 coefficient
qui reg Y Z ddd* [pw = weight_12m], vce(cluster household_id)
scalar itt = _b[Z]

* Estimate first stage and retrieve coefficient
reg D Z ddd* [pw = weight_12m], vce(cluster household_id)
scalar fs = _b[Z]

* Compute Indirect least squares
di "The Indirect Least Squares estimate is " itt / fs
(sum of wgt is 28,909.5595551729)

Linear regression                               Number of obs     =     23,514
                                                F(17, 20809)      =     125.61
                                                Prob > F          =     0.0000
                                                R-squared         =     0.1092
                                                Root MSE          =     .42414

                      (Std. err. adjusted for 20,810 clusters in household_id)
------------------------------------------------------------------------------
             |               Robust
           D | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
           Z |   .2899314   .0066785    43.41   0.000     .2768411    .3030217
ddddraw_su~2 |  -.0458972   .0170392    -2.69   0.007    -.0792954   -.0124991
ddddraw_su~3 |   -.049708   .0174966    -2.84   0.005    -.0840027   -.0154133
ddddraw_su~4 |  -.0636485   .0158866    -4.01   0.000    -.0947874   -.0325095
ddddraw_su~5 |  -.0682771   .0158315    -4.31   0.000     -.099308   -.0372461
ddddraw_su~6 |  -.0636407   .0148206    -4.29   0.000    -.0926902   -.0345912
ddddraw_su~7 |   -.077627   .0142663    -5.44   0.000    -.1055899    -.049664
dddnumhh_l~2 |  -.1113067   .0214158    -5.20   0.000    -.1532834   -.0693299
dddnumhh_l~3 |  -.0126071   .1172338    -0.11   0.914    -.2423945    .2171803
ddddraxn~2_2 |   .0356131   .0303819     1.17   0.241    -.0239377    .0951639
ddddraxn~2_3 |  -.1630362    .155808    -1.05   0.295     -.468432    .1423596
ddddraxn~3_2 |   .0585528   .0315021     1.86   0.063    -.0031938    .1202993
ddddraxn~3_3 |  -.0859646   .2175038    -0.40   0.693     -.512289    .3403598
ddddraxn~4_2 |   .0740766   .0289888     2.56   0.011     .0172563    .1308969
ddddraxn~5_2 |   .0599303   .0285146     2.10   0.036     .0040395    .1158211
ddddraxn~6_2 |   .0639389   .0262383     2.44   0.015     .0125097    .1153681
ddddraxn~7_2 |   .0772291   .0460712     1.68   0.094     -.013074    .1675323
       _cons |   .2088795   .0125937    16.59   0.000     .1841949    .2335642
------------------------------------------------------------------------------
The Indirect Least Squares estimate is .02233335

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 2SLS
ivregress 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 Wald
sum Y if Z==1
local YZ1 = r(mean)
sum Y if Z==0
local YZ0 = r(mean)

sum D if Z==1
local DZ1 = r(mean)
sum D if Z==0
local 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 IV
corr Y Z, cov
local CovYZ = r(cov_12)

corr D Z, cov
local 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:

import delimited "data/Clingingsmith_et_al_2009.csv", clear
(encoding automatically selected: ISO-8859-2)
(160 vars, 1,605 obs)

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 Z

dis "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.

gen illiterate = 1 - literate
gen rural = 1 - urban

Now we summarise these variables to ensure that they do indeed coincide with those documented in the paper’s Table 2:

* Matrix to store means
matrix stat_df = J(5,2,.)
matrix colnames stat_df = "Full Sample" "Compliers"
matrix rownames stat_df = "Age" "Female" "Illiterate" "Urban" "Rural"

* Counter to iterate through matrix rows
local rowcounter = 0

* For each covariate
foreach vari of varlist age female illiterate urban rural{
    * Add one to row counter
        local rowcounter = `rowcounter' + 1

    * Summarize variable
    qui sum `vari'

    * Assign the mean
    matrix define stat_df[`rowcounter', 1] = r(mean)
}

* Show matrix
matrix list 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 score using probit
qui probit Z female age urban literate

* Predict probabilities
predict PrZ1, pr
gen PrZ0 = 1 - PrZ1

We then compute Abadie’s kappa using the estimated probabilities:

* Compute Abadie's kappa
gen 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:

histogram Kappa, scheme(plottig) title("Abadie's Kappa Distribution") ///
 xtitle("Abadie's Kappa") ytitle("") fraction ylabel(, format(%3.2f))
(bin=32, start=-1.3681374, width=.07400429)

Abadie’s Kappa Distribution

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 denominator
sum Kappa
scalar PrD1 = r(mean)

* Complier's mean estimate
local rowcounter = 0
foreach vari of varlist age female illiterate urban rural{
    local rowcounter = `rowcounter' + 1
    qui replace `vari' = `vari' * Kappa
    qui sum `vari'
    matrix define stat_df[`rowcounter', 2] = r(mean) / PrD1
}

* Show results
matrix list 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.

import delimited "data/Bhalotra_Clarke_2020.csv", clear
(encoding automatically selected: ISO-8859-1)
(41 vars, 4,028,554 obs)

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.

forvalues j = 4/11{
  gen fert`j' = (fert >= `j') & (fert != .) 
}

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).

keep if 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 code
encode _cou, generate(num_cou)

* Contraceptive intent code
encode contracep_intent, generate(num_contracep_intent)

* Keep families with 3+ childs
keep if 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.

forvalues j = 4/11 {
    reghdfe fert`j' twin_three_fam malec agefirstbirth [pw=sweight], absorb(motherage num_cou year_birth num_contracep_intent age bord) vce(cluster id)  nofootnote noheader
    matrix define ACR[`j' - 3, 1] = `j'
    matrix define ACR[`j' - 3, 2] = _b[twin_three_fam]
    matrix define ACR[`j' - 3, 3] = _se[twin_three_fam]
    matrix define ACR[`j' - 3, 4] = _b[twin_three_fam] + invnormal(0.025) * _se[twin_three_fam]
    matrix define ACR[`j' - 3, 5] = _b[twin_three_fam] + invnormal(0.975) * _se[twin_three_fam]
}
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert4 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .3929582   .0038128   103.06   0.000     .3854852    .4004311
       malec |  -.0173752   .0010674   -16.28   0.000    -.0194673   -.0152831
agefirstbi~h |   .0073506   .0004674    15.73   0.000     .0064345    .0082666
       _cons |   .4630176   .0091174    50.78   0.000     .4451478    .4808874
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert5 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .1722929   .0065321    26.38   0.000     .1594902    .1850956
       malec |  -.0096684   .0010209    -9.47   0.000    -.0116693   -.0076675
agefirstbi~h |   .0042594   .0004162    10.23   0.000     .0034437    .0050751
       _cons |   .2759666   .0081126    34.02   0.000     .2600661     .291867
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert6 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .1072543   .0059982    17.88   0.000     .0954981    .1190106
       malec |  -.0014181   .0008709    -1.63   0.103     -.003125    .0002888
agefirstbi~h |   .0015005   .0003422     4.38   0.000     .0008297    .0021713
       _cons |   .1778429   .0066727    26.65   0.000     .1647647    .1909212
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert7 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .0714688   .0050179    14.24   0.000     .0616339    .0813037
       malec |   .0022131   .0007002     3.16   0.002     .0008407    .0035855
agefirstbi~h |   .0001105   .0002683     0.41   0.680    -.0004154    .0006364
       _cons |   .1117386   .0052363    21.34   0.000     .1014758    .1220015
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert8 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .0398832   .0038499    10.36   0.000     .0323375    .0474288
       malec |   .0030942   .0005341     5.79   0.000     .0020473    .0041411
agefirstbi~h |  -.0000651   .0001947    -0.33   0.738    -.0004468    .0003166
       _cons |   .0605633   .0038016    15.93   0.000     .0531122    .0680143
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
       fert9 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .0201147   .0027277     7.37   0.000     .0147685     .025461
       malec |   .0017987   .0003941     4.56   0.000     .0010263    .0025712
agefirstbi~h |  -.0000832   .0001418    -0.59   0.557    -.0003611    .0001947
       _cons |   .0310176   .0027671    11.21   0.000     .0255942    .0364409
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
      fert10 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |   .0118583   .0019967     5.94   0.000     .0079449    .0157717
       malec |   .0008247   .0002752     3.00   0.003     .0002854     .001364
agefirstbi~h |  -.0000106    .000092    -0.12   0.908     -.000191    .0001697
       _cons |   .0140693   .0018019     7.81   0.000     .0105376     .017601
------------------------------------------------------------------------------
(MWFE estimator converged in 9 iterations)
                               (Std. err. adjusted for 648,620 clusters in id)
------------------------------------------------------------------------------
             |               Robust
      fert11 | Coefficient  std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
twin_three~m |    .007745   .0015685     4.94   0.000     .0046707    .0108192
       malec |   .0002649   .0001853     1.43   0.153    -.0000982     .000628
agefirstbi~h |  -.0000499   .0000591    -0.84   0.398    -.0001658    .0000659
       _cons |    .007081   .0011554     6.13   0.000     .0048165    .0093455
------------------------------------------------------------------------------

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 data
svmat ACR

// Rename variables
rename (ACR1 ACR2 ACR3 ACR4 ACR5) (Childs_plus Point SE LB UB)

// Generate Plot
twoway scatter 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 dataset
import delimited "data/Bhalotra_Clarke_2020.csv", clear

// Gen dummies for at least j children
forvalues j = 4/11 {
  gen fert`j' = (fert >= `j') & (fert != .) 
}

// Keep USA data
keep if datasource == "NHIS"

// Keep if has at least three childs
keep if three_plus == 1

// Matrix to store results
matrix ACR = J(8, 5, .)

local FEs motherage surveyyear ageinterview region motherrace childsex
// Estimates
forvalues j = 4/11 {
    qui reghdfe fert`j' twin_three_fam agefirstbirth  [pw = sweight], absorb(`FEs') vce(cluster mid)
    matrix define ACR[`j'-3, 1] = `j'
    matrix define ACR[`j'-3, 2] = _b[twin_three_fam]
    matrix define ACR[`j'-3, 3] = _se[twin_three_fam]
    matrix define ACR[`j'-3, 4] = _b[twin_three_fam] + invnormal(0.025) * _se[twin_three_fam]
    matrix define ACR[`j'-3, 5] = _b[twin_three_fam] + invnormal(0.975) * _se[twin_three_fam]
}

// Assign to data
svmat ACR   

// Rename variables
rename (ACR1 ACR2 ACR3 ACR4 ACR5) (Childs_plus Point SE LB UB)

// Plot results
twoway scatter 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)
(encoding automatically selected: ISO-8859-1)
(41 vars, 4,028,554 obs)
(3,801,341 observations deleted)
(173,814 observations deleted)

ACR Function for USA

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:

use "data/Duflo_et_al_2024", clear
keep if e2_testtaker==1
(22,420 observations deleted)

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.

ivregress 2sls e2_engmath_ASER_theta female i.strata (tarl=anytreat), cluster(schcode)

Instrumental-variables 2SLS regression            Number of obs   =     28,356
                                                  Wald chi2(41)   =    1108.01
                                                  Prob > chi2     =     0.0000
                                                  R-squared       =     0.1222
                                                  Root MSE        =     .98217

                              (Std. err. adjusted for 500 clusters in schcode)
------------------------------------------------------------------------------
             |               Robust
e2_engmath.. | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
        tarl |   .2493792   .1316311     1.89   0.058    -.0086131    .5073715
      female |  -.0212688   .0127937    -1.66   0.096     -.046344    .0038063
             |
      strata |
          2  |  -.0984759   .1086478    -0.91   0.365    -.3114217    .1144699
          3  |   .5334908   .1081554     4.93   0.000     .3215101    .7454714
          4  |   .4557069   .1007937     4.52   0.000     .2581548    .6532589
          5  |  -.1005356   .1056994    -0.95   0.342    -.3077027    .1066315
          6  |  -.1128326   .1292694    -0.87   0.383     -.366196    .1405307
          7  |   .0823298   .1032826     0.80   0.425    -.1201003    .2847599
          8  |   .3159635   .1067525     2.96   0.003     .1067325    .5251945
          9  |   .0575935   .1004606     0.57   0.566    -.1393057    .2544926
         10  |   .1102604   .1010468     1.09   0.275    -.0877876    .3083084
         11  |   .4989038   .1326422     3.76   0.000     .2389299    .7588777
         12  |   .4242503   .0956672     4.43   0.000      .236746    .6117546
         13  |    .235534   .1007963     2.34   0.019     .0379768    .4330911
         14  |   .1807432   .1445331     1.25   0.211    -.1025365     .464023
         15  |   .5722203   .0956057     5.99   0.000     .3848366    .7596041
         16  |   .6792021   .1320197     5.14   0.000     .4204483    .9379559
         17  |   .6835563   .0917972     7.45   0.000     .5036371    .8634755
         18  |   .0833724   .1026321     0.81   0.417    -.1177829    .2845277
         19  |   .9336304   .1132502     8.24   0.000     .7116641    1.155597
         20  |   1.085386   .0981354    11.06   0.000     .8930445    1.277728
         21  |   -.592578    .114965    -5.15   0.000    -.8179052   -.3672508
         22  |  -.1817902   .1269096    -1.43   0.152    -.4305285     .066948
         23  |  -.2677713   .2936033    -0.91   0.362    -.8432233    .3076806
         24  |   .4581905   .1288304     3.56   0.000     .2056876    .7106935
         25  |  -.0808301   .1827414    -0.44   0.658    -.4389967    .2773364
         26  |  -.2409277   .1013402    -2.38   0.017    -.4395509   -.0423046
         27  |   .4468737   .1591747     2.81   0.005      .134897    .7588503
         28  |   .3886053   .1144258     3.40   0.001     .1643348    .6128758
         29  |  -.3549158   .1148498    -3.09   0.002    -.5800172   -.1298144
         30  |  -.0694557   .1006027    -0.69   0.490    -.2666334    .1277219
         31  |   .4435237    .223157     1.99   0.047     .0061439    .8809035
         32  |   .2228456   .1118056     1.99   0.046     .0037106    .4419807
         33  |   .0884757    .111195     0.80   0.426    -.1294625    .3064139
         34  |  -.1045054   .1108233    -0.94   0.346     -.321715    .1127043
         35  |   .4932788    .118876     4.15   0.000     .2602861    .7262716
         36  |   .5304534   .1375536     3.86   0.000     .2608533    .8000536
         37  |   .1492261   .0991855     1.50   0.132    -.0451738    .3436261
         38  |   .0697935   .1052011     0.66   0.507    -.1363969    .2759839
         39  |    .409759   .1121159     3.65   0.000      .190016    .6295021
         40  |   .5714214   .0982954     5.81   0.000     .3787658    .7640769
             |
       _cons |  -.5208934    .084246    -6.18   0.000    -.6860125   -.3557743
------------------------------------------------------------------------------
Endogenous: tarl
Exogenous:  female 2.strata 3.strata 4.strata 5.strata 6.strata 7.strata
            8.strata 9.strata 10.strata 11.strata 12.strata 13.strata
            14.strata 15.strata 16.strata 17.strata 18.strata 19.strata
            20.strata 21.strata 22.strata 23.strata 24.strata 25.strata
            26.strata 27.strata 28.strata 29.strata 30.strata 31.strata
            32.strata 33.strata 34.strata 35.strata 36.strata 37.strata
            38.strata 39.strata 40.strata anytreat

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*female
gen Z2 = anytreat*(1-female)
(1,075 missing values generated)
(1,075 missing values generated)

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:

ivregress 2sls e2_engmath_ASER_theta female (tarl=Z1 Z2), cluster(schcode)
local IV2SLS = _b[tarl]

Instrumental-variables 2SLS regression            Number of obs   =     28,356
                                                  Wald chi2(2)    =       1.44
                                                  Prob > chi2     =     0.4868
                                                  R-squared       =     0.0057
                                                  Root MSE        =     1.0453

                              (Std. err. adjusted for 500 clusters in schcode)
------------------------------------------------------------------------------
             |               Robust
e2_engmath.. | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
        tarl |   .2356772   .2090026     1.13   0.259    -.1739603    .6453148
      female |  -.0057894   .0134803    -0.43   0.668    -.0322102    .0206315
       _cons |  -.2991058   .0496061    -6.03   0.000     -.396332   -.2018797
------------------------------------------------------------------------------
Endogenous: tarl
Exogenous:  female Z1 Z2

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]

Instrumental-variables 2SLS regression            Number of obs   =     13,514
                                                  Wald chi2(1)    =       2.38
                                                  Prob > chi2     =     0.1228
                                                  R-squared       =     0.0078
                                                  Root MSE        =     1.0506

                              (Std. err. adjusted for 499 clusters in schcode)
------------------------------------------------------------------------------
             |               Robust
e2_engmath.. | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
        tarl |    .348505   .2258463     1.54   0.123    -.0941456    .7911557
       _cons |  -.3287428   .0537215    -6.12   0.000     -.434035   -.2234505
------------------------------------------------------------------------------
Endogenous: tarl
Exogenous:  anytreat

Instrumental-variables 2SLS regression            Number of obs   =     14,842
                                                  Wald chi2(1)    =       0.37
                                                  Prob > chi2     =     0.5403
                                                  R-squared       =     0.0034
                                                  Root MSE        =     1.0407

                              (Std. err. adjusted for 498 clusters in schcode)
------------------------------------------------------------------------------
             |               Robust
e2_engmath.. | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
        tarl |   .1283069   .2095256     0.61   0.540    -.2823558    .5389695
       _cons |  -.2764009   .0495771    -5.58   0.000    -.3735702   -.1792315
------------------------------------------------------------------------------
Endogenous: tarl
Exogenous:  anytreat

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 female
predict Dhat

sum Dhat if female==1
local V1 = r(Var)

sum Dhat if female==0
local 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:

sum female
local P1 = r(mean)
local P2 = 1-r(mean)

local Vtot   = `P1'*`V1'+`P2'*`V2' 
local omega1 = `P1'*`V1'/`Vtot'
local omega2 = `P2'*`V2'/`Vtot'

    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 Dhat
levelsof strata, local(stratvals)
local i = 1
foreach s of local stratvals {
    foreach w of numlist 0 1 {
        gen X`i' = strata==`s'&female==`w'
        gen Z`i' = X`i'*anytreat

        // Confirm variation of Z within this covariate level
        qui sum anytreat if X`i'==1
        if r(sd)==0 drop X`i' Z`i'

        local ++i
    }
}
// Drop a number of variables where there is no variation in endogenous variable by IV
drop X33 Z33 X34 Z34
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3
> 0 31 32 33 34 35 36 37 38 39 40

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.

ivregress 2sls e2_engmath_ASER_theta X* (tarl=Z*), cluster(schcode)
local IV2SLS = _b[tarl]

Instrumental-variables 2SLS regression            Number of obs   =     29,431
                                                  Wald chi2(75)   =    1197.26
                                                  Prob > chi2     =     0.0000
                                                  R-squared       =     0.1195
                                                  Root MSE        =     .98162

                              (Std. err. adjusted for 500 clusters in schcode)
------------------------------------------------------------------------------
             |               Robust
e2_engmath.. | Coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
        tarl |   .2184165   .1254261     1.74   0.082    -.0274141     .464247
          X1 |  -.2068919   .0880174    -2.35   0.019     -.379403   -.0343809
          X2 |  -.2650911     .11601    -2.29   0.022    -.4924666   -.0377156
          X3 |  -.2942251   .1033487    -2.85   0.004    -.4967848   -.0916654
          X4 |  -.3827059   .0826233    -4.63   0.000    -.5446446   -.2207673
          X5 |    .299764   .0889923     3.37   0.001     .1253423    .4741857
          X6 |   .2957554   .0945206     3.13   0.002     .1104984    .4810124
          X7 |   .2207067   .0788193     2.80   0.005     .0662237    .3751897
          X8 |    .226459   .0802252     2.82   0.005     .0692204    .3836976
          X9 |  -.2762745   .0941991    -2.93   0.003    -.4609013   -.0916477
         X10 |  -.4040329    .087924    -4.60   0.000    -.5763608    -.231705
         X11 |  -.3277006   .1207179    -2.71   0.007    -.5643033   -.0910979
         X12 |  -.3729248   .1172927    -3.18   0.001    -.6028142   -.1430355
         X13 |  -.1424111   .0895016    -1.59   0.112    -.3178311    .0330088
         X14 |  -.1592128   .0877355    -1.81   0.070    -.3311712    .0127457
         X15 |   .0955108    .085817     1.11   0.266    -.0726875    .2637091
         X16 |   .0702821   .1010219     0.70   0.487    -.1277172    .2682813
         X17 |   -.231412   .0857636    -2.70   0.007    -.3995056   -.0633183
         X18 |  -.1137952   .0848479    -1.34   0.180     -.280094    .0525036
         X19 |   -.107893   .0859618    -1.26   0.209    -.2763751    .0605891
         X20 |  -.1533321   .0850178    -1.80   0.071    -.3199639    .0132998
         X21 |   .2278724     .13756     1.66   0.098    -.0417402    .4974851
         X22 |   .3221079    .072581     4.44   0.000     .1798518     .464364
         X23 |   .2251659   .0730673     3.08   0.002     .0819566    .3683751
         X24 |   .1456594   .0850981     1.71   0.087    -.0211298    .3124485
         X25 |   .0155049   .0817979     0.19   0.850    -.1448161    .1758258
         X26 |   -.026744   .0931777    -0.29   0.774    -.2093689    .1558809
         X27 |  -.1251302   .1415377    -0.88   0.377    -.4025389    .1522785
         X28 |   .0180666   .1310428     0.14   0.890    -.2387725    .2749057
         X29 |   .3199601   .0709408     4.51   0.000     .1809186    .4590015
         X30 |   .3511034   .0803076     4.37   0.000     .1937034    .5085035
         X31 |   .3996045   .1178246     3.39   0.001     .1686725    .6305366
         X32 |   .4882733   .1188023     4.11   0.000      .255425    .7211216
         X37 |    .616836   .0906615     6.80   0.000     .4391427    .7945293
         X38 |   .7922958   .1070637     7.40   0.000     .5824549    1.002137
         X39 |   .8067332   .0883155     9.13   0.000      .633638    .9798284
         X40 |   .8977715   .0861297    10.42   0.000     .7289605    1.066583
         X41 |  -.7522268   .0978511    -7.69   0.000    -.9440115   -.5604421
         X42 |  -.9314381   .0970723    -9.60   0.000    -1.121696   -.7411799
         X43 |  -.3443397    .104407    -3.30   0.001    -.5489736   -.1397057
         X44 |  -.5164886   .1223823    -4.22   0.000    -.7563534   -.2766238
         X45 |  -.4062647   .2689984    -1.51   0.131    -.9334919    .1209625
         X46 |  -.5905764   .3153545    -1.87   0.061     -1.20866    .0275071
         X47 |   .2301825   .1008884     2.28   0.023     .0324448    .4279202
         X48 |   .2081514   .1306254     1.59   0.111    -.0478696    .4641725
         X49 |  -.3555792   .1569955    -2.26   0.024    -.6632847   -.0478736
         X50 |  -.2822735   .2107209    -1.34   0.180    -.6952788    .1307318
         X51 |  -.5504617   .0801261    -6.87   0.000     -.707506   -.3934173
         X52 |  -.3903959   .0981744    -3.98   0.000    -.5828143   -.1979776
         X53 |   .2203059   .1053095     2.09   0.036      .013903    .4267087
         X54 |   .2019058   .1805499     1.12   0.263    -.1519655    .5557771
         X55 |   .0760486   .0810173     0.94   0.348    -.0827423    .2348395
         X56 |   .2158933   .1499625     1.44   0.150    -.0780279    .5098145
         X57 |  -.5072568   .1159232    -4.38   0.000     -.734462   -.2800516
         X58 |  -.6889483   .1134599    -6.07   0.000    -.9113256    -.466571
         X59 |  -.2609332   .1053233    -2.48   0.013     -.467363   -.0545034
         X60 |  -.3491963   .0923977    -3.78   0.000    -.5302924   -.1681001
         X63 |   .0232269   .0954679     0.24   0.808    -.1638867    .2103405
         X64 |  -.0551508   .1172588    -0.47   0.638    -.2849737    .1746722
         X65 |  -.1148331   .0900415    -1.28   0.202    -.2913112     .061645
         X66 |  -.1873047   .0993747    -1.88   0.059    -.3820756    .0074662
         X67 |  -.3199293   .0824382    -3.88   0.000    -.4815052   -.1583534
         X68 |  -.3645361   .1188582    -3.07   0.002    -.5974939   -.1315784
         X69 |   .1752511   .0970523     1.81   0.071    -.0149679    .3654702
         X70 |   .3304188   .1112437     2.97   0.003     .1123852    .5484523
         X71 |   .2959659    .109048     2.71   0.007     .0822356    .5096961
         X72 |   .2985707   .1456752     2.05   0.040     .0130525    .5840889
         X73 |   -.024909     .08406    -0.30   0.767    -.1896636    .1398457
         X74 |  -.1590094   .0797559    -1.99   0.046     -.315328   -.0026907
         X75 |  -.1474923   .0925195    -1.59   0.111    -.3288272    .0338426
         X76 |   -.187701   .0807468    -2.32   0.020    -.3459619   -.0294401
         X77 |    .166933   .0910076     1.83   0.067    -.0114386    .3453046
         X78 |   .1905451   .1209642     1.58   0.115    -.0465404    .4276306
         X79 |    .335161     .08871     3.78   0.000     .1612925    .5090294
         X80 |   .3403613     .07075     4.81   0.000     .2016938    .4790288
       _cons |  -.2886095   .0597392    -4.83   0.000    -.4056961   -.1715229
------------------------------------------------------------------------------
Endogenous: tarl
Exogenous:  X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18
            X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31 X32 X37 X38
            X39 X40 X41 X42 X43 X44 X45 X46 X47 X48 X49 X50 X51 X52 X53 X54
            X55 X56 X57 X58 X59 X60 X63 X64 X65 X66 X67 X68 X69 X70 X71 X72
            X73 X74 X75 X76 X77 X78 X79 X80 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 Z10
            Z11 Z12 Z13 Z14 Z15 Z16 Z17 Z18 Z19 Z20 Z21 Z22 Z23 Z24 Z25 Z26
            Z27 Z28 Z29 Z30 Z31 Z32 Z37 Z38 Z39 Z40 Z41 Z42 Z43 Z44 Z45 Z46
            Z47 Z48 Z49 Z50 Z51 Z52 Z53 Z54 Z55 Z56 Z57 Z58 Z59 Z60 Z63 Z64
            Z65 Z66 Z67 Z68 Z69 Z70 Z71 Z72 Z73 Z74 Z75 Z76 Z77 Z78 Z79 Z80

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!

foreach var of varlist X* {
    qui ivregress 2sls e2_engmath_ASER_theta (tarl=anytreat) if `var'==1, cluster(schcode)
    local IV`var' = _b[tarl]
}

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 weights
local Vtot = 0
foreach var of varlist X* {
    qui sum Dhat if `var'==1
    local V`var' = r(Var)
    qui sum `var'
    local P`var' = r(mean)
    local Vtot = `Vtot' + `P`var''*`V`var''
}

      Source |       SS           df       MS      Number of obs   =    29,431
-------------+----------------------------------   F(148, 29282)   =     55.78
       Model |  480.291964       148  3.24521597   Prob > F        =    0.0000
    Residual |  1703.49274    29,282  .058175423   R-squared       =    0.2199
-------------+----------------------------------   Adj R-squared   =    0.2160
       Total |  2183.78471    29,430  .074202674   Root MSE        =     .2412

------------------------------------------------------------------------------
        tarl | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
          Z1 |         .3   .0289554    10.36   0.000      .243246     .356754
          Z2 |   .2877323   .0282492    10.19   0.000     .2323626    .3431021
          Z3 |   .1774461   .0322447     5.50   0.000      .114245    .2406472
          Z4 |   .1919701   .0341465     5.62   0.000     .1250415    .2588987
          Z5 |   .2760763   .0249432    11.07   0.000     .2271865     .324966
          Z6 |   .3055355   .0235056    13.00   0.000     .2594635    .3516075
          Z7 |   .3888543   .0176707    22.01   0.000      .354219    .4234896
          Z8 |   .3813834   .0193151    19.75   0.000      .343525    .4192418
          Z9 |   .2334234   .0232371    10.05   0.000     .1878776    .2789692
         Z10 |    .236531   .0239987     9.86   0.000     .1894926    .2835695
         Z11 |   .2456667   .0325915     7.54   0.000     .1817858    .3095475
         Z12 |   .2332112   .0359224     6.49   0.000     .1628017    .3036208
         Z13 |   .3489583   .0471049     7.41   0.000     .2566306     .441286
         Z14 |   .3731343   .0472082     7.90   0.000     .2806042    .4656645
         Z15 |   .4233677   .0237495    17.83   0.000     .3768177    .4699177
         Z16 |   .4044177   .0244593    16.53   0.000     .3564764    .4523589
         Z17 |   .2806634   .0259793    10.80   0.000     .2297429     .331584
         Z18 |   .2449612   .0284325     8.62   0.000     .1892323    .3006901
         Z19 |     .10575   .0301812     3.50   0.000     .0465935    .1649065
         Z20 |   .1088757   .0288652     3.77   0.000     .0522986    .1654529
         Z21 |   .1145038   .0464234     2.47   0.014     .0235119    .2054957
         Z22 |   .2462687   .0536129     4.59   0.000      .141185    .3513523
         Z23 |   .2198997   .0311487     7.06   0.000     .1588469    .2809524
         Z24 |   .2249104   .0348072     6.46   0.000     .1566868     .293134
         Z25 |   .1129762   .0274023     4.12   0.000     .0592665    .1666859
         Z26 |   .1417763   .0280177     5.06   0.000     .0868603    .1966923
         Z27 |   .2237903   .0497514     4.50   0.000     .1262753    .3213054
         Z28 |   .1986726   .0509168     3.90   0.000     .0988734    .2984718
         Z29 |   .2685865   .0215713    12.45   0.000     .2263059    .3108672
         Z30 |   .2858954   .0212963    13.42   0.000     .2441536    .3276372
         Z31 |   .1985232   .0265831     7.47   0.000     .1464192    .2506272
         Z32 |   .1985547   .0293013     6.78   0.000     .1411228    .2559865
         Z37 |   .4417122   .0401333    11.01   0.000      .363049    .5203754
         Z38 |   .4302083   .0382262    11.25   0.000     .3552832    .5051335
         Z39 |   .3392982   .0344985     9.84   0.000     .2716796    .4069169
         Z40 |   .3227879   .0359008     8.99   0.000     .2524206    .3931551
         Z41 |   .2318678   .0229116    10.12   0.000     .1869601    .2767755
         Z42 |   .2237705   .0267955     8.35   0.000     .1712502    .2762908
         Z43 |    .142623   .0252712     5.64   0.000     .0930902    .1921557
         Z44 |   .1255968   .0278065     4.52   0.000     .0710949    .1800987
         Z45 |   .4622642   .0486498     9.50   0.000     .3669083      .55762
         Z46 |   .3551402   .0443013     8.02   0.000     .2683076    .4419728
         Z47 |   .1758741   .0314574     5.59   0.000     .1142163     .237532
         Z48 |   .1521073   .0290135     5.24   0.000     .0952396     .208975
         Z49 |    .094086    .063621     1.48   0.139    -.0306139     .218786
         Z50 |   .0853659   .0642771     1.33   0.184    -.0406201    .2113518
         Z51 |    .219697   .0324253     6.78   0.000      .156142    .2832519
         Z52 |   .2135628   .0349507     6.11   0.000     .1450578    .2820677
         Z53 |   .2772727   .0593783     4.67   0.000     .1608886    .3936569
         Z54 |   .2907407   .0629345     4.62   0.000     .1673864    .4140951
         Z55 |   .2622951   .0537855     4.88   0.000     .1568732     .367717
         Z56 |   .2575758   .0495354     5.20   0.000     .1604842    .3546673
         Z57 |   .1973684   .0550188     3.59   0.000     .0895291    .3052078
         Z58 |   .1948925   .0504663     3.86   0.000     .0959762    .2938087
         Z59 |   .3046683    .029498    10.33   0.000      .246851    .3624857
         Z60 |   .3160622   .0293287    10.78   0.000     .2585767    .3735477
         Z63 |   .2519189   .0293266     8.59   0.000     .1944374    .3094003
         Z64 |   .2678571   .0298654     8.97   0.000     .2093197    .3263946
         Z65 |   .1770833   .0315349     5.62   0.000     .1152735    .2388932
         Z66 |   .1658249   .0346252     4.79   0.000     .0979581    .2336918
         Z67 |   .2085308   .0457569     4.56   0.000     .1188452    .2982164
         Z68 |   .2168367   .0531618     4.08   0.000     .1126372    .3210363
         Z69 |   .2502094   .0284122     8.81   0.000     .1945202    .3058986
         Z70 |   .2485316   .0295631     8.41   0.000     .1905865    .3064766
         Z71 |   .3918831   .0462672     8.47   0.000     .3011973    .4825689
         Z72 |    .396841   .0432656     9.17   0.000     .3120385    .4816434
         Z73 |   .2279635   .0331699     6.87   0.000      .162949    .2929781
         Z74 |   .2223183   .0372633     5.97   0.000     .1492806    .2953561
         Z75 |    .202509     .03736     5.42   0.000     .1292817    .2757362
         Z76 |   .1977401   .0365773     5.41   0.000     .1260469    .2694333
         Z77 |   .5140562   .0568355     9.04   0.000     .4026561    .6254564
         Z78 |   .5425532   .0561093     9.67   0.000     .4325764      .65253
         Z79 |   .3588435   .0263956    13.59   0.000      .307107    .4105801
         Z80 |   .3353909   .0273795    12.25   0.000     .2817259     .389056
          X1 |  -.2253504   .0256973    -8.77   0.000    -.2757184   -.1749825
          X2 |  -.2253504   .0249644    -9.03   0.000    -.2742817   -.1764192
          X3 |  -.2253504   .0306018    -7.36   0.000    -.2853314   -.1653695
          X4 |  -.2253504   .0323186    -6.97   0.000    -.2886963   -.1620046
          X5 |  -.2253504   .0235858    -9.55   0.000    -.2715797   -.1791211
          X6 |  -.2253504   .0221126   -10.19   0.000    -.2686922   -.1820087
          X7 |  -.2253504   .0171262   -13.16   0.000    -.2589186   -.1917823
          X8 |  -.2253504   .0185173   -12.17   0.000    -.2616453   -.1890556
          X9 |  -.2253504   .0205961   -10.94   0.000    -.2657197   -.1849812
         X10 |  -.2253504   .0211728   -10.64   0.000      -.26685   -.1838509
         X11 |  -.2253504   .0301621    -7.47   0.000    -.2844696   -.1662313
         X12 |  -.2253504   .0334483    -6.74   0.000    -.2909106   -.1597903
         X13 |  -.2253504   .0445044    -5.06   0.000    -.3125812   -.1381197
         X14 |  -.2253504   .0445044    -5.06   0.000    -.3125812   -.1381197
         X15 |  -.2253504   .0220352   -10.23   0.000    -.2685405   -.1821604
         X16 |  -.2253504   .0223504   -10.08   0.000    -.2691582   -.1815427
         X17 |  -.2253504    .023983    -9.40   0.000    -.2723582   -.1783427
         X18 |  -.2253504   .0260913    -8.64   0.000    -.2764905   -.1742103
         X19 |  -.2253504   .0284065    -7.93   0.000    -.2810285   -.1696724
         X20 |  -.2253504   .0265056    -8.50   0.000    -.2773027   -.1733982
         X21 |  -.2253504    .041863    -5.38   0.000    -.3074037   -.1432972
         X22 |  -.2253504   .0452495    -4.98   0.000    -.3140414   -.1366595
         X23 |  -.2253504   .0285856    -7.88   0.000    -.2813795   -.1693214
         X24 |  -.2253504   .0323186    -6.97   0.000    -.2886963   -.1620046
         X25 |  -.2253504   .0255703    -8.81   0.000    -.2754693   -.1752316
         X26 |  -.2253504    .025201    -8.94   0.000    -.2747456   -.1759553
         X27 |  -.2253504   .0452495    -4.98   0.000    -.3140414   -.1366595
         X28 |  -.2253504   .0460343    -4.90   0.000    -.3155798   -.1351211
         X29 |  -.2253504   .0202402   -11.13   0.000    -.2650221   -.1856788
         X30 |  -.2253504     .02007   -11.23   0.000    -.2646885   -.1860124
         X31 |  -.2253504   .0245121    -9.19   0.000    -.2733953   -.1773056
         X32 |  -.2253504   .0272465    -8.27   0.000    -.2787549    -.171946
         X37 |  -.2253504   .0365274    -6.17   0.000    -.2969458   -.1537551
         X38 |  -.2253504   .0337508    -6.68   0.000    -.2915035   -.1591974
         X39 |  -.2253504   .0320545    -7.03   0.000    -.2881787   -.1625222
         X40 |  -.2253504   .0334483    -6.74   0.000    -.2909106   -.1597903
         X41 |  -.2253504   .0215894   -10.44   0.000    -.2676667   -.1830342
         X42 |  -.2253504   .0249644    -9.03   0.000    -.2742817   -.1764192
         X43 |  -.2253504   .0236831    -9.52   0.000    -.2717704   -.1789305
         X44 |  -.2253504   .0256973    -8.77   0.000    -.2757184   -.1749825
         X45 |  -.2253504   .0431213    -5.23   0.000    -.3098701   -.1408307
         X46 |  -.2253504   .0382149    -5.90   0.000    -.3002533   -.1504475
         X47 |  -.2253504   .0287684    -7.83   0.000    -.2817378   -.1689631
         X48 |  -.2253504   .0256973    -8.77   0.000    -.2757184   -.1749825
         X49 |  -.2253504   .0588519    -3.83   0.000    -.3407029    -.109998
         X50 |  -.2253504   .0588519    -3.83   0.000    -.3407029    -.109998
         X51 |  -.2253504   .0299497    -7.52   0.000    -.2840533   -.1666476
         X52 |  -.2253504   .0320545    -7.03   0.000    -.2881787   -.1625222
         X53 |  -.2253504   .0530257    -4.25   0.000    -.3292832   -.1214177
         X54 |  -.2253504   .0588519    -3.83   0.000    -.3407029    -.109998
         X55 |  -.2253504   .0445044    -5.06   0.000    -.3125812   -.1381197
         X56 |  -.2253504   .0401718    -5.61   0.000     -.304089   -.1466119
         X57 |  -.2253504   .0518247    -4.35   0.000    -.3269292   -.1237716
         X58 |  -.2253504   .0460343    -4.90   0.000    -.3155798   -.1351211
         X59 |  -.2253504   .0277247    -8.13   0.000    -.2796921   -.1710088
         X60 |  -.2253504   .0274029    -8.22   0.000    -.2790614   -.1716394
         X63 |  -.2253504   .0266486    -8.46   0.000    -.2775829    -.173118
         X64 |  -.2253504   .0265056    -8.50   0.000    -.2773027   -.1733982
         X65 |  -.2253504   .0291454    -7.73   0.000    -.2824768   -.1682241
         X66 |  -.2253504   .0323186    -6.97   0.000    -.2886963   -.1620046
         X67 |  -.2253504   .0431213    -5.23   0.000    -.3098701   -.1408307
         X68 |  -.2253504   .0507034    -4.44   0.000    -.3247313   -.1259696
         X69 |  -.2253504   .0265056    -8.50   0.000    -.2773027   -.1733982
         X70 |  -.2253504   .0280589    -8.03   0.000    -.2803472   -.1703537
         X71 |  -.2253504   .0424777    -5.31   0.000    -.3086087   -.1420922
         X72 |  -.2253504   .0391554    -5.76   0.000    -.3020967   -.1486042
         X73 |  -.2253504   .0310626    -7.25   0.000    -.2862345   -.1644664
         X74 |  -.2253504   .0350531    -6.43   0.000    -.2940561   -.1566448
         X75 |  -.2253504   .0350531    -6.43   0.000    -.2940561   -.1566448
         X76 |  -.2253504   .0343825    -6.55   0.000    -.2927418   -.1579591
         X77 |  -.2253504   .0507034    -4.44   0.000    -.3247313   -.1259696
         X78 |  -.2253504   .0507034    -4.44   0.000    -.3247313   -.1259696
         X79 |  -.2253504   .0246227    -9.15   0.000    -.2736119   -.1770889
         X80 |  -.2253504   .0254452    -8.86   0.000    -.2752242   -.1754767
       _cons |   .2253504   .0064393    35.00   0.000     .2127291    .2379718
------------------------------------------------------------------------------
(option xb assumed; fitted values)

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 = 0
local omega    = 0
foreach var of varlist 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.