library("knitr") knitr::opts_knit$set(self.contained = FALSE) knitr::opts_chunk$set(tidy = TRUE, collapse=TRUE, comment = "#>", tidy.opts=list(blank=FALSE, width.cutoff=55)) oldoptions <- options(digits=5)
The package ATEHonest
implements honest confidence intervals and estimators
for estimating average treatment effects under unconfoundedness from @ak17ate.
Here we illustrate the use of the package using NSW data from @DeWa99.
The data is shipped with the package, as two data frames, NSW
(where the
treated units are from the experimental sample and control units are from PSID),
and NSWexper
, where both treated and control units are from the experimental
sample. We'll use the experimental sample here.
First we extract the design matrix, and the treatment and outcome vectors:
library("ATEHonest") X <- as.matrix(NSWexper[, 2:10]) d <- NSWexper$treated y <- NSWexper$re78
Next, we compute matrix of distances between treated and control units, using the same weight matrix to compute distances as in @ak17ate:
Ahalf <- diag(c(0.15, 0.6, 2.5, 2.5, 2.5, 0.5, 0.5, 0.1, 0.1)) D0 <- distMat(X, Ahalf, method="manhattan", d)
Next, construct a distance matrix used by the nearest neighbor variance estimator to estimate the conditional variance of the outcome. We use Mahalanobis distance:
DM <- distMat(X, chol(solve(cov(X))), method="euclidean")
We are now ready to compute the root mean squared error optimal estimator:
c1 <- ATTOptEstimate(y=y, d=d, D0=D0, C=1, DM=DM, opt.criterion="RMSE") print(c1)
Next, we compute the estimator that's optimal for constructing two-sided CIs. We
re-use the solution path returned by c1
:
ATTOptEstimate(path=c1$path, C=1, DM=DM, opt.criterion="FLCI")
For computing efficiency of one- and two-sided CIs at smooth functions (see Appendix A in @ak17ate), the solution path is not long enough:
ATTEffBounds(c1$path, DM=DM, C=1)
We therefore make it longer, by passing the output c1$path
as an argument to
ATTOptPath
(at the moment, only the ATTOptEstimate
can automatically compute
extra steps in the solution path as needed):
op <- ATTOptPath(path=c1$path, maxsteps=290) ATTEffBounds(op, DM=DM, C=1)
For comparison, we also consider matching estimators. First, a matching estimator with a single match:
ATTMatchEstimate(ATTMatchPath(y, d, D0, M=1, tol=1e-12), C=1, DM=DM)
Next, we optimize the number of matches. For that we first compute the matching
estimator for a vector of matches M
, and then optimize the number of matches
using ATTMatchEstmate
:
mp <- ATTMatchPath(y, d, D0, M=1:10, tol=1e-12) ATTMatchEstimate(mp, C=1, DM=DM, opt.criterion="FLCI") ATTMatchEstimate(mp, C=1, DM=DM, opt.criterion="RMSE")
We can see that a single match is in fact optimal for both estimation and construction of two-sided CIs.
options(oldoptions)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.