*! version 30aug2024

Flexible partially-linear IV model - Detailed example with pystacked

Here will illustrate how to do standard- and short-stacking with the flexible IV model.

Note: Support for pystacked integration is relatively limited for the flexible IV model.
In particular, short-stacking requires that individual learners appear in separate pystacked commands,
pooled stacking is not available, and re-stacking with ddml estimate is also not available.

First we illustrate how to do standard stacking with pystacked.
To start, we load the data, define global macros, set the seed and initialize the model.

. use https://github.com/aahrens1/ddml/raw/master/data/BLP.dta, clear

. global Y share

. global D price

. global X hpwt air mpd space

. global Z sum*

. set seed 42

. ddml init fiv

Adding learners for E[Y|X] is the same as for other ddml linear models:

. ddml E[Y|X]: pystacked $Y $X, type(reg)

Adding learners for E[D|Z,X] and E[D|X] in the fiv model is different
from how it's done in the partialiv model.
The reason for this is that the estimation of E[D|X]
depends on the estimation of E[D|X,Z].

When adding learners for E[D|Z,X],
we need to provide a name for each learners using learner(name).
Here we use the name "Dhat_pys".

. ddml E[D|Z,X], learner(Dhat_pys): pystacked $D $X $Z, type(reg)

When adding learners for E[D|X], we explicitly refer to the name of the learner from
the previous step (here, "Dhat_pys").
We also provide the name of the treatment variable (vname($D)),
and we use the placeholder in place of the dependent variable.

. ddml E[D|X], learner(Dhat_pys) vname($D): pystacked $X, type(reg)

The crossfit and estimation commands with the fiv model are standard.

. ddml crossfit

. ddml estimate, robust

The stacking weights and other results from pystacked are available via ddml extract.
Note this is only the case if pystacked is the single learner in each equation.

. ddml extract, show(stweights)

. ddml extract, show(pystacked)

To replicate what ddml does in the background:

. cap drop Ytilde

. cap drop Dtilde

. cap drop Ztilde

. gen double Ytilde = $Y - Y1_pystacked_1

. gen Dtilde = $D - Dhat_pys_h_1

. gen Zopt = Dhat_pys_1 - Dhat_pys_h_1

. ivreg Ytilde (Dtilde=Zopt), robust

Next we illustrate how to do short-stacking with the flexible IV model.
We again use pystacked, but the procedure applies to any set of learners.
Here we use the same learners as in the standard stacking estimation with pystacked above,
in order to facilitate direct comparison of the two sets of results.
We begin by re-initializing the model.

. set seed 42

. ddml init fiv

We add learners for E[Y|X] in the usual way,
but we need to specify each pystacked learner in a separate equation.

. ddml E[Y|X]: pystacked $Y $X, type(reg) m(ols)

. ddml E[Y|X]: pystacked $Y $X, type(reg) m(lassocv)

. ddml E[Y|X]: pystacked $Y $X, type(reg) m(gradboost)

As above, when adding learners for E[D|Z,X],
we need to provide a name for each learner using learner(name).

. ddml E[D|Z,X], learner(Dhat_ols): pystacked $D $X $Z, type(reg) m(ols)

. ddml E[D|Z,X], learner(Dhat_lassocv): pystacked $D $X $Z, type(reg) m(lassocv)

. ddml E[D|Z,X], learner(Dhat_gradboost): pystacked $D $X $Z, type(reg) m(gradboost)

Again as above, when adding learners for E[D|X],
we explicitly refer to the learner from the previous step,
the name of the treatment variable (vname($D)),
and the placeholder in place of the dependent variable.

. ddml E[D|X], learner(Dhat_ols) vname($D): pystacked $X, type(reg) m(ols)

. ddml E[D|X], learner(Dhat_lassocv) vname($D): pystacked $X, type(reg) m(lassocv)

. ddml E[D|X], learner(Dhat_gradboost) vname($D): pystacked $X, type(reg) m(gradboost)

Short-stacking is requested when cross-fitting.
Short-stacking weights can be examined using ddml extract.

. ddml crossfit, shortstack

. ddml estimate, robust

. ddml extract, show(ssweights)