| Title: | Quantile Treatment Effects |
| Version: | 2.0.0 |
| Description: | Provides several methods for computing the Quantile Treatment Effect (QTE) and Quantile Treatment Effect on the Treated (QTT). The main cases covered are (i) treatment is randomly assigned, (ii) treatment is as good as randomly assigned after conditioning on covariates (selection on observables) using the methods of Firpo (2007) <doi:10.1111/j.1468-0262.2007.00738.x>, and (iii) identification is based on a Difference in Differences assumption, with support for several varieties including Athey and Imbens (2006) <doi:10.1111/j.1468-0262.2006.00668.x>, Callaway and Li (2019) <doi:10.3982/QE935>, and Callaway, Li, and Oka (2018) <doi:10.1016/j.jeconom.2018.06.008>. Version 2.0 adds a unified staggered treatment adoption API (built on 'ptetools') for all DiD-based estimators, as well as a new lagged-outcome unconfoundedness estimator ('lou_qtt'). |
| Depends: | R (≥ 3.5) |
| Imports: | parallel, quantreg, BMisc, formula.tools, ggplot2, rlang, pbapply, data.table, ptetools (≥ 1.0.1) |
| URL: | https://bcallaway11.github.io/qte/, https://github.com/bcallaway11/qte |
| BugReports: | https://github.com/bcallaway11/qte/issues |
| License: | GPL-3 |
| Encoding: | UTF-8 |
| LazyData: | true |
| VignetteBuilder: | knitr, quarto |
| Suggests: | rmarkdown, knitr, msm, testthat (≥ 3.0.0), did, quarto |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-07-23 02:44:17 UTC; bmc43193 |
| Author: | Brantly Callaway [aut, cre] |
| Maintainer: | Brantly Callaway <brantly.callaway@uga.edu> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-23 10:50:15 UTC |
qte: A package for computing quantile treatment effects
Description
Provides several methods for computing the Quantile Treatment Effect (QTE) and Quantile Treatment Effect on the Treated (QTT). The main cases covered are (i) treatment is randomly assigned, (ii) treatment is as good as randomly assigned after conditioning on covariates (selection on observables) using the methods of Firpo (2007) doi:10.1111/j.1468-0262.2007.00738.x, and (iii) identification is based on a Difference in Differences assumption, with support for several varieties including Athey and Imbens (2006) doi:10.1111/j.1468-0262.2006.00668.x, Callaway and Li (2019) doi:10.3982/QE935, and Callaway, Li, and Oka (2018) doi:10.1016/j.jeconom.2018.06.008. Version 2.0 adds a unified staggered treatment adoption API (built on 'ptetools') for all DiD-based estimators, as well as a new lagged-outcome unconfoundedness estimator ('lou_qtt').
Author(s)
Maintainer: Brantly Callaway brantly.callaway@uga.edu
Authors:
Brantly Callaway brantly.callaway@uga.edu
See Also
Useful links:
Report bugs at https://github.com/bcallaway11/qte/issues
CiC
Description
Deprecated. Use cic instead.
CiC is a legacy two-period wrapper for the Change in Changes
estimator. It accepts a formula and explicit t/tmin1 time
period arguments. The modern replacement cic uses a
yname/gname/tname interface and supports staggered
treatment adoption natively via ptetools.
Usage
CiC(
formla,
xformla = NULL,
t,
tmin1,
tname,
data,
panel = FALSE,
se = TRUE,
idname = NULL,
alp = 0.05,
probs = seq(0.05, 0.95, 0.05),
iters = 100,
pl = FALSE,
cores = 2,
retEachIter = FALSE
)
Arguments
formla |
formula of the form |
xformla |
optional one-sided covariate formula. |
t |
post-treatment period. |
tmin1 |
pre-treatment period. |
tname |
name of the time column. |
data |
data.frame. |
panel |
logical; whether data are panel. |
se |
logical; whether to compute bootstrap SEs. |
idname |
name of the unit id column (required when |
alp |
significance level. |
probs |
quantile grid. |
iters |
bootstrap iterations. |
pl |
logical; parallel bootstrap. |
cores |
number of cores. |
retEachIter |
logical; return per-iteration results. |
Value
QTE object.
See Also
MDiD
Description
Deprecated. Use mdid instead.
MDiD is a legacy two-period wrapper for the Mean
Difference-in-Differences estimator. The modern replacement
mdid uses a yname/gname/tname
interface and supports staggered treatment adoption natively.
Usage
MDiD(
formla,
xformla = NULL,
t,
tmin1,
tname,
data,
panel = FALSE,
se = TRUE,
idname = NULL,
alp = 0.05,
probs = seq(0.05, 0.95, 0.05),
iters = 100,
retEachIter = FALSE,
biters = NULL
)
Arguments
formla |
formula of the form |
xformla |
optional one-sided covariate formula (unused in this estimator; accepted for consistency with other wrappers). |
t |
post-treatment period. |
tmin1 |
pre-treatment period. |
tname |
name of the time column. |
data |
data.frame. |
panel |
logical; whether data are panel. |
se |
logical; whether to compute bootstrap SEs. |
idname |
name of the unit id column (required when |
alp |
significance level. |
probs |
quantile grid. |
iters |
bootstrap iterations. |
retEachIter |
logical; return per-iteration results. |
biters |
alias for |
Value
QTE object.
See Also
QDiD
Description
Deprecated. Use qdid instead.
QDiD is a legacy two-period wrapper for the Quantile
Difference-in-Differences estimator. It accepts a formula and explicit
t/tmin1 time period arguments. The modern replacement
qdid uses a yname/gname/tname
interface and supports staggered treatment adoption natively.
Usage
QDiD(
formla,
xformla = NULL,
t,
tmin1,
tname,
data,
panel = FALSE,
se = TRUE,
idname = NULL,
alp = 0.05,
probs = seq(0.05, 0.95, 0.05),
iters = 100,
retEachIter = FALSE,
pl = FALSE,
cores = NULL,
biters = NULL,
cl = NULL
)
Arguments
formla |
formula of the form |
xformla |
optional one-sided covariate formula. |
t |
post-treatment period. |
tmin1 |
pre-treatment period. |
tname |
name of the time column. |
data |
data.frame. |
panel |
logical; whether data are panel. |
se |
logical; whether to compute bootstrap SEs. |
idname |
name of the unit id column. |
alp |
significance level. |
probs |
quantile grid. |
iters |
bootstrap iterations. |
retEachIter |
logical; return per-iteration results. |
pl |
logical; parallel bootstrap. |
cores |
number of cores. |
biters |
alias for |
cl |
alias for |
Value
QTE object.
See Also
QTE
Description
Main class of objects. A QTE object is returned by
all of the methods that compute the QTE or QTET.
Usage
QTE(
qte,
ate = NULL,
qte.se = NULL,
qte.lower = NULL,
qte.upper = NULL,
ate.se = NULL,
ate.lower = NULL,
ate.upper = NULL,
c = NULL,
alp = 0.05,
pscore.reg = NULL,
probs,
type = "On the Treated",
F.treated.t = NULL,
F.untreated.t = NULL,
F.treated.t.cf = NULL,
F.treated.tmin1 = NULL,
F.treated.tmin2 = NULL,
F.treated.change.tmin1 = NULL,
F.untreated.change.t = NULL,
F.untreated.change.tmin1 = NULL,
F.untreated.tmin1 = NULL,
F.untreated.tmin2 = NULL,
condQ.treated.t = NULL,
condQ.treated.t.cf = NULL,
eachIterList = NULL,
inffunct = NULL,
inffuncu = NULL
)
Arguments
qte |
The Quantile Treatment Effect at each value of probs |
ate |
The Average Treatment Effect (or Average Treatment Effect on the Treated) |
qte.se |
A vector of standard errors for each qte |
qte.lower |
A vector of lower confidence intervals for each qte (it is based on the bootstrap confidence interval – not the se – so it may not be symmyetric about the qte |
qte.upper |
A vector of upper confidence intervals for each qte (it is based on the bootstrap confidence interval – not the se – so it may not be symmetric about the qte |
ate.se |
The standard error for the ATE |
ate.lower |
Lower confidence interval for the ATE (it is based on the bootstrap confidence intervall – not the se – so it may not be symmetric about the ATE |
ate.upper |
Upper confidence interval for the ATE (it is based on the bootstrap confidence interval – not the se – so it may not be symmetric about the ATE |
c |
The critical value from a KS-type statistic used for creating uniform confidence bands |
alp |
The significance level |
pscore.reg |
The results of propensity score regression, if specified |
probs |
The values for which the qte is computed |
type |
Takes the values "On the Treated" or "Population" to indicate whether the estimated QTE is for the treated group or for the entire population |
F.treated.t |
Distribution of treated outcomes for the treated group at period t |
F.untreated.t |
Distribution of untreated potential outcomes for the untreated group at period t |
F.treated.t.cf |
Counterfactual distribution of untreated potential outcomes for the treated group at period t |
F.treated.tmin1 |
Distribution of treated outcomes for the treated group at period tmin1 |
F.treated.tmin2 |
Distribution of treated outcomes for the treated group at period tmin2 |
F.treated.change.tmin1 |
Distribution of the change in outcomes for the treated group between periods tmin1 and tmin2 |
F.untreated.change.t |
Distribution of the change in outcomes for the untreated group between periods t and tmin1 |
F.untreated.change.tmin1 |
Distribution of the change in outcomes for the untreated group between periods tmin1 and tmin2 |
F.untreated.tmin1 |
Distribution of outcomes for the untreated group in period tmin1 |
F.untreated.tmin2 |
Distribution of outcomes for the untreated group in period tmin2 |
condQ.treated.t |
Conditional quantiles for the treated group in period t |
condQ.treated.t.cf |
Counterfactual conditional quantiles for the treated group in period t |
eachIterList |
An optional list of the outcome of each bootstrap iteration |
inffunct |
The influence function for the treated group; used for inference when there are multiple periods and in the case with panel data. It is needed for computing covariance terms in the variance-covariance matrix. |
inffuncu |
The influence function for the untreated group |
QTEparams
Description
QTEparams is an object that contains all the
parameters passed to QTE methods
Usage
QTEparams(
formla,
xformla = NULL,
t = NULL,
tmin1 = NULL,
tmin2 = NULL,
tname = NULL,
data,
panel = FALSE,
w = NULL,
idname = NULL,
probs,
alp = NULL,
method = NULL,
plot = NULL,
se = NULL,
iters = NULL,
retEachIter = NULL,
bootstrapiter = NULL,
seedvec = NULL,
pl = NULL,
cores = NULL,
est_method = NULL,
target = NULL
)
Arguments
formla |
Should be some y on treatment variable |
xformla |
a formula for the other covariates such as ~ x1 + x2 |
t |
The last period (not always used) |
tmin1 |
The last pre-treatment period (not always used) |
tmin2 |
The 2nd to last pre-treatment period (not always used) |
tname |
The name of the column containing time periods (not always used) |
data |
The name of the data frame |
panel |
Whether or not the data is panel |
w |
Additional (usually sampling) weights |
idname |
The name of the id column used with panel data (not always used) |
probs |
Which quantiles to produce quantile treatment effects for |
alp |
The significance level |
method |
The method to compute the propensity score |
plot |
boolean for whether or not to plot qtes |
se |
boolean whether or not to compute standard errors |
iters |
The number of bootstrap iterations to use to compute standard errors |
retEachIter |
boolean whether or not to return the full results from each bootstrap iteration |
bootstrapiter |
Used internally for determining whether or not a call is part of computing standard errors via the bootstrap |
seedvec |
A seed to compute the same bootstrap standard errors each time the method is called (not always used) |
pl |
Boolean for whether or not computing bootstrap standard errrors in parallel |
cores |
The number of cores to use if computing standard errors in in parallel |
est_method |
Estimation method: |
target |
Target parameter: |
Value
A named list with class "QTEparams" containing all supplied
arguments. Used internally by legacy estimators (CiC, QDiD,
MDiD, ddid2, panel.qtet, ci.qtet) to pass
parameters to setupData and compute.* functions.
SE
Description
Class for Standard Error Objects
Usage
SE(
qte.se = NULL,
ate.se = NULL,
qte.upper = NULL,
qte.lower = NULL,
ate.upper = NULL,
ate.lower = NULL,
c = NULL,
probs = NULL
)
Arguments
qte.se |
The QTE Standard Error |
ate.se |
The ATE Standard Error |
qte.upper |
The QTE upper CI |
qte.lower |
The QTE lower CI |
ate.upper |
The ATE upper CI |
ate.lower |
The ATE lower CI |
c |
The critical value from a KS-type statistic used for creating uniform confidence bands |
probs |
The values at which the QTE is computed |
autoplot.QTE
Description
Plot a QTE object as a quantile treatment effect curve
with optional confidence bands.
Usage
## S3 method for class 'QTE'
autoplot(object, cband = TRUE, ylab = "QTE", ...)
Arguments
object |
a |
cband |
logical; if |
ylab |
label for the y-axis. Default |
... |
unused. |
Value
a ggplot object.
bootiter
Description
bootiter that computes a single bootstrap iteration
Usage
bootiter(i, qteparams, func)
Arguments
i |
the bootstrap iteration, this is not used except for calling by apply-type methods |
qteparams |
QTEparams object containing the parameters passed to ciqte |
func |
the internal function that computes estimates of the qte, should be the same as what was used to produce qteest |
Value
SE object
bootstrap
Description
bootstrap is a method that bootstraps standard
errors for methods in the qte package
Usage
bootstrap(qteparams, qteest, func)
Arguments
qteparams |
QTEparams object containing the parameters passed to ciqte |
qteest |
an initial estimate of the qte |
func |
the internal function that computes estimates of the qte, should be the same as what was used to produce qteest |
Value
SE object
ci.qte
Description
Deprecated. Use unc_qte instead.
Usage
ci.qte(
formla,
xformla = NULL,
x = NULL,
data,
w = NULL,
probs = seq(0.05, 0.95, 0.05),
se = TRUE,
iters = 100,
alp = 0.05,
method = "logit",
retEachIter = FALSE,
printIter = FALSE,
pl = FALSE,
cores = 2,
biters = NULL,
cl = NULL
)
Arguments
formla |
formula of the form |
xformla |
one-sided covariate formula. Default |
x |
ignored (deprecated argument). |
data |
data.frame. |
w |
sampling weight vector. Cannot be forwarded automatically;
use |
probs |
quantile grid. |
se |
ignored; bootstrap is always run in |
iters |
number of bootstrap iterations. |
alp |
significance level. |
method |
propensity score model. |
retEachIter |
ignored. |
printIter |
ignored. |
pl |
logical; whether to run bootstrap in parallel. |
cores |
number of cores. |
biters |
alias for |
cl |
alias for cores; takes precedence if supplied. |
Value
A QTE object; same structure as unc_qte.
ci.qtet
Description
Deprecated. Use unc_qte(target = "qtt")
for a cross-sectional QTT under unconfoundedness, or lou_qtt
for staggered treatment adoption with optional lagged-outcome conditioning.
ci.qtet estimates the Quantile Treatment Effect on the Treated
(QTET) under a Conditional Independence Assumption (sometimes called
Selection on Observables) following Firpo (2007). It uses propensity score
re-weighting to estimate the counterfactual distribution. Standard errors
are computed via the bootstrap.
Usage
ci.qtet(
formla,
xformla = NULL,
w = NULL,
data,
probs = seq(0.05, 0.95, 0.05),
se = TRUE,
iters = 100,
alp = 0.05,
method = "logit",
retEachIter = FALSE,
indsample = TRUE,
printIter = FALSE,
pl = FALSE,
cores = 2,
biters = NULL,
cl = NULL
)
Arguments
formla |
The formula y ~ d where y is the outcome and d is the treatment indicator (d should be binary), d should be equal to one in all time periods for individuals that are eventually treated |
xformla |
A optional one sided formula for additional covariates that will be adjusted for. E.g ~ age + education. Additional covariates can also be passed by name using the x paramater. |
w |
sampling weight vector. Cannot be forwarded automatically;
use |
data |
A data.frame containing all the variables used |
probs |
A vector of values between 0 and 1 to compute the QTET at |
se |
Boolean whether or not to compute standard errors |
iters |
The number of iterations to compute bootstrap standard errors. This is only used if se=TRUE |
alp |
The significance level used for constructing bootstrap confidence intervals |
method |
Method to compute propensity score. Default is logit; other option is probit. |
retEachIter |
Boolean whether or not to return list of results from each iteration of the bootstrap procedure (default is FALSE). This is potentially useful for debugging but can cause errors due to running out of memory. |
indsample |
Binary variable for whether to treat the samples as independent or dependent. This affects bootstrap standard errors. In the job training example, the samples are independent because they are two samples collected independently and then merged. If the data is from the same source, usually should set this option to be FALSE. |
printIter |
For debugging only; should leave at default FALSE unless you want to see a lot of output |
pl |
Whether or not to compute standard errors in parallel |
cores |
Number of cores to use if computing in parallel |
biters |
Number of bootstrap iterations; alias for |
cl |
Number of cores for parallel bootstrap; alias for
|
Value
A QTE object; same structure as unc_qte.
References
Firpo, Sergio. “Efficient Semiparametric Estimation of Quantile Treatment Effects.” Econometrica 75.1, pp. 259-276, 2007.
Examples
# See ?unc_qte for the modern replacement.
## Not run:
data(lalonde)
## Estimate the QTET of participating in the job training program;
## This is the no covariate case. Note: Because individuals that participate
## in the job training program are likely to be much different than
## individuals that do not (e.g. less experience and less education), this
## method is likely to perform poorly at estimating the true QTET
q1 <- ci.qtet(re78 ~ treat,
x = NULL, data = lalonde.psid, se = FALSE,
probs = seq(0.05, 0.95, 0.05)
)
summary(q1)
## This estimation controls for all the available background characteristics.
q2 <- ci.qtet(re78 ~ treat,
xformla = ~ age + I(age^2) + education + black + hispanic + married + nodegree,
data = lalonde.psid, se = FALSE, probs = seq(0.05, 0.95, 0.05)
)
summary(q2)
## End(Not run)
Change in Changes
Description
Computes Quantile Treatment effects on the Treated (QTT) and the Average Treatment Effect on the Treated (ATT) using the Change in Changes identification strategy of Athey and Imbens (2006). Handles two-period data and staggered treatment adoption uniformly: a two-period, two-group dataset is the degenerate single-(g,t) case. Supports both panel and repeated cross sections data.
Usage
cic(
yname,
gname,
tname,
idname = NULL,
data,
panel = TRUE,
xformula = ~1,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
ret_quantile = NULL,
gt_type = "att",
probs = NULL
)
Arguments
yname |
Name of the outcome variable in |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable. Required when
|
data |
A data frame. |
panel |
Logical; |
xformula |
One-sided formula for covariates used in the covariate
adjustment. Default |
weightsname |
Name of the column in |
control_group |
Which units to use as the comparison group:
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level for confidence bands. Default |
cband |
Logical; if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of clusters for parallel computation. Default |
ret_quantile |
Passed through to |
gt_type |
Type of group-time effect to compute. |
probs |
For |
Value
For gt_type = "att", a pte_results object from
ptetools. For gt_type = "qtt", a pte_qtt object
with overall, group-specific, and dynamic QTT curves and bootstrap SEs.
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
Examples
data(mpdta, package = "did")
## ATT aggregated across all groups and periods
res_att <- cic(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "att", biters = 20)
summary(res_att)
## Full QTT curve at selected quantiles
res_qtt <- cic(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20)
summary(res_qtt)
Change in Changes: group-time estimator
Description
Computes the Change in Changes (CiC) ATT and counterfactual
outcome distribution for a single 2x2 (pre/post x treated/control) data
subset. Serves directly as the attgt_fun argument to
ptetools::pte. Panel vs. repeated cross sections is detected
automatically from whether the same unit ids appear in both periods.
Usage
cic_gt(gt_data, xformula = ~1, ...)
Arguments
gt_data |
A data frame (typically a |
xformula |
One-sided formula for covariates. Default |
... |
Additional arguments passed through by |
Value
A ptetools::attgt_noif object with the ATT estimate and, in
extra_gt_returns, three objects: F1 (ECDF of observed
treated outcomes in the post period), F0 (ECDF of counterfactual
untreated outcomes for the treated group), and Fte (ECDF of
individual treatment effects under rank invariance; NULL for
repeated cross sections).
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
compute.panel.qtet
Description
compute.panel.qtet uses third period of data,
combined with Distributional
Difference in Differences assumption (Fan and Yu, 2012)
to point identify QTET.
Usage
compute.panel.qtet(qp)
Arguments
qp |
QTEparams object |
Value
QTE object
compute.unc_qte
Description
Computes the QTE or QTT under unconfoundedness. Dispatches to
IPW, OR (outcome regression), or AIPW based on qp$est_method and
qp$target. Called internally by unc_qte and during each
bootstrap iteration.
Usage
compute.unc_qte(qp)
Arguments
qp |
QTEparams object |
Value
QTE object
computeSE
Description
Computes standard errors from bootstrap results. This function is called by several functions in the qte package
Usage
computeSE(bootIters, qteobj, alp = 0.05)
Arguments
bootIters |
List of bootstrap iterations |
alp |
The significance level used for constructing bootstrap confidence intervals |
Value
SEObj
Distributional Difference-in-Differences
Description
Computes Quantile Treatment effects on the Treated (QTT) and
the Average Treatment Effect on the Treated (ATT) using the distributional
DiD identification strategy of Callaway, Li, and Oka (2018). Handles
two-period data and staggered treatment adoption uniformly via
ptetools. Requires panel data.
Identification. Under distributional parallel trends and a copula
restriction (the rank correlation of untreated potential outcomes between
the treated and control groups in the pre-period is preserved), the
counterfactual distribution F_{Y(0),\text{post}|D=1} is recovered
by adding each control unit's actual change \Delta Y_{\text{ctrl},j}
to the treated pre-period quantile at that control unit's rank. This
point-identifies the QTT with only two time periods, in contrast to
methods (e.g. panel_qtt) that require three periods.
Panel data required. Unlike cic, qdid, and
mdid, this estimator cannot be applied to repeated cross sections
because it requires observing the within-unit outcome change for each
control unit.
Usage
ddid(
yname,
gname,
tname,
idname,
data,
xformula = ~1,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
gt_type = "att",
probs = NULL
)
Arguments
yname |
Name of the outcome variable in |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable (required). |
data |
A data frame. |
xformula |
One-sided formula for covariates. Default |
weightsname |
Name of the column in |
control_group |
Which units to use as the comparison group:
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level for confidence bands. Default |
cband |
Logical; if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of clusters for parallel computation. Default |
gt_type |
Type of group-time effect to compute. |
probs |
For |
Value
For gt_type = "att", a pte_results object from
ptetools. For gt_type = "qtt", a pte_qtt object.
References
Callaway, Brantly, Tong Li, and Tatsushi Oka. “Quantile Treatment Effects in Difference in Differences Models under Dependence Restrictions and with Only Two Time Periods.” Journal of Econometrics 206(2), pp. 395-413, 2018.
Examples
data(mpdta, package = "did")
## ATT aggregated across all groups and periods
res_att <- ddid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "att", biters = 20)
summary(res_att)
## Full QTT curve at selected quantiles
res_qtt <- ddid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20)
summary(res_qtt)
ddid2
Description
Deprecated. Use ddid instead.
ddid2 is a legacy two-period wrapper for the Distributional
Difference-in-Differences estimator. The modern replacement
ddid uses a yname/gname/tname
interface and supports staggered treatment adoption natively.
Usage
ddid2(
formla,
xformla = NULL,
t,
tmin1,
tname,
data,
panel = TRUE,
dropalwaystreated = TRUE,
idname = NULL,
probs = seq(0.05, 0.95, 0.05),
iters = 100,
alp = 0.05,
method = "logit",
se = TRUE,
retEachIter = FALSE,
seedvec = NULL,
pl = FALSE,
cores = NULL,
biters = NULL,
cl = NULL
)
Arguments
formla |
formula of the form |
xformla |
optional one-sided covariate formula. |
t |
post-treatment period. |
tmin1 |
pre-treatment period. |
tname |
name of the time column. |
data |
data.frame. |
panel |
logical; whether data are panel (must be |
dropalwaystreated |
logical; whether to drop always-treated units. |
idname |
name of the unit id column. |
probs |
quantile grid. |
iters |
bootstrap iterations. |
alp |
significance level. |
method |
propensity score estimation method ( |
se |
logical; whether to compute bootstrap SEs. |
retEachIter |
logical; return per-iteration results. |
seedvec |
optional vector of seeds for reproducible bootstrap. |
pl |
logical; parallel bootstrap. |
cores |
number of cores. |
biters |
alias for |
cl |
alias for |
Value
QTE object.
See Also
Distributional DiD: group-time estimator
Description
Computes the distributional DiD ATT and counterfactual outcome
distribution for a single 2x2 (pre/post x treated/control) data subset.
Serves directly as the attgt_fun argument to ptetools::pte.
Identification. Under distributional parallel trends and a copula
restriction (Callaway, Li, and Oka 2018), the counterfactual outcome for
each control unit j is
kcf_j = \Delta Y_{\text{ctrl},j} + Q_{1,\text{pre}}(u_j)
where \Delta Y_{\text{ctrl},j} = Y_{\text{post},j} - Y_{\text{pre},j}
is the observed change for control unit j, u_j =
F_{0,\text{pre}}(Y_{\text{pre},j}) is that unit's rank in the control
pre-period distribution, and Q_{1,\text{pre}} is the quantile
function of the treated pre-period distribution. The unconditional
counterfactual distribution F_{Y(0),\text{post}|D=1} is then the
(weighted) empirical CDF of \{kcf_j\}.
Unlike CiC, QDiD, and MDiD, the counterfactual is indexed over
control units, not treated units. Consequently F0 and the
ATT counterfactual term are weighted by w_pre_ctrl, and no
individual treatment effect distribution (Fte) is returned.
Panel data required. The estimator needs the actual change
\Delta Y_{\text{ctrl},j} for each control unit, which requires
observing the same units in both periods.
Usage
ddid_gt(gt_data, xformula = ~1, ...)
Arguments
gt_data |
A data frame (typically a |
xformula |
One-sided formula for covariates. Default |
... |
Additional arguments passed through by |
Value
A ptetools::attgt_noif object with the ATT estimate and, in
extra_gt_returns, F0 (weighted ECDF of counterfactual
outcomes indexed over control units), F1 (weighted ECDF of observed
treated post-period outcomes), and Fte = NULL (individual treatment
effect distribution is not identified for this estimator).
References
Callaway, Brantly, Tong Li, and Tatsushi Oka. “Quantile Treatment Effects in Difference in Differences Models under Dependence Restrictions and with Only Two Time Periods.” Journal of Econometrics 206(2), pp. 395-413, 2018.
ggqte
Description
Deprecated. Use autoplot() on a QTE
object instead.
Usage
ggqte(
qteobj,
main = "",
ylab = "QTE",
ylim = NULL,
ybreaks = NULL,
xbreaks = c(0.1, 0.3, 0.5, 0.7, 0.9),
setype = "pointwise",
alp = qteobj$alp
)
Arguments
qteobj |
a QTE object |
main |
optional title |
ylab |
optional y axis label |
ylim |
optional limits of y axis |
ybreaks |
optional breaks in y axis |
xbreaks |
optional breaks in x axis |
setype |
options are "pointwise", "uniform" or both |
alp |
significance level override |
Value
a ggplot object
Lalonde (1986)'s NSW Dataset
Description
lalonde contains data from the National Supported Work
Demonstration. This program randomly assigned applicants to the job
training program (or out of the job training program). The dataset is
discussed in Lalonde (1986). The experimental part of the dataset is
combined with an observational dataset from the Panel Study of Income
Dynamics (PSID). Lalonde (1986) and many subsequent papers (e.g.
Heckman and Hotz (1989), Dehejia and Wahba (1999), Smith and Todd (2005),
and Firpo (2007) have used this combination to study the effectiveness
of various ‘observational’ methods (e.g. regression, Heckman selection,
Difference in Differences, and propensity score matching) of estimating
the Average Treatment Effect (ATE) of participating in the job training
program. The idea is that the results from the observational method
can be compared to results that can be easily obtained from the
experimental portion of the dataset.
To be clear, the observational data combines the observations that are treated from the experimental portion of the data with untreated observations from the PSID.
Usage
data(lalonde)
Format
Four data.frames: (i) lalonde.exp contains a cross sectional version of the experimental data, (ii) lalonde.psid contains a cross sectional version of the observational data, (iii) lalonde.exp.panel contains a panel version of the experimental data, and (iv) lalonde.psid.panel contains a panel version of the observational data. Note: the cross sectional and panel versions of each dataset are identical up to their shape; in demonstrating each of the methods, it is sometimes convenient to have one form of the data or the other.
References
LaLonde, Robert. “Evaluating the Econometric Evaluations of
Training Programs with Experimental Data.” The American Economics Review,
pp. 604-620, 1986.
@source The dataset comes from Lalonde (1986) and has been studied in much
subsequent work. The qte package uses a version from the
causalsens package
(https://CRAN.R-project.org/package=causalsens)
Lalonde's Experimental Dataset
Description
The cross sectional verion of the experimental part of the
lalonde dataset. It
is loaded with all the datasets with the command data(lalonde)
Lalonde's Panel Experimental Dataset
Description
The panel verion of the experimental part of the
lalonde dataset. It
is loaded with all the datasets with the command data(lalonde)
Lalonde's Observational Dataset
Description
The cross sectional verion of the observational part of the
lalonde dataset. It
is loaded with all the datasets with the command data(lalonde)
Lalonde's Panel Observational Dataset
Description
The panel verion of the observational part of the
lalonde dataset. It
is loaded with all the datasets with the command data(lalonde)
lou_gt
Description
Estimates the ATT and counterfactual distribution
F_0 = F_{Y(0)|D=1} for a single (g,t) cell under lagged-outcome
unconfoundedness. Called internally by lou_qtt via
ptetools::pte().
Usage
lou_gt(
gt_data,
xformula = ~1,
lagged_outcome_cov = TRUE,
est_method = "ipw",
...
)
Arguments
gt_data |
A |
xformula |
One-sided covariate formula. Default |
lagged_outcome_cov |
Logical; if |
est_method |
One of |
... |
Additional arguments (ignored). |
Value
A list from ptetools::attgt_noif with attgt (ATT) and
extra_gt_returns containing F0 and F1 (weighted ECDFs
of counterfactual and observed treated outcomes).
Lagged Outcome Unconfoundedness QTT
Description
Estimates the Quantile Treatment Effect on the Treated (QTT)
and Average Treatment Effect on the Treated (ATT) under a lagged-outcome
unconfoundedness assumption with staggered treatment adoption. The key
identifying assumption is
Y_{g,t}(0) \perp D \mid X, Y_{\text{pre}}, i.e., conditional on
observed covariates and the pre-treatment outcome, treatment is as good
as randomly assigned within each cohort-period cell.
Estimation operates at the (g,t) level: for each cohort g and
post-treatment period t, a cross-sectional comparison is made
between the treated group and a not-yet-treated (or never-treated)
comparison group, adjusting for covariates and (optionally) the
pre-treatment outcome. Group-time estimates are then aggregated to
overall, dynamic, and group-specific summaries.
Three estimation methods are available:
"ipw"Propensity-score reweighting. Control units are reweighted by
\hat p(X,Y_{\text{pre}})/(1-\hat p(X,Y_{\text{pre}}))to approximate the covariate distribution of the treated group."or"Outcome regression. A quantile regression model is fit on control units' post-period outcomes as a function of
(X, Y_{\text{pre}}), then predicted at treated units to construct the counterfactual distribution (Melly 2006; Chernozhukov, Fernandez-Val, and Melly 2013)."aipw"Doubly-robust augmented IPW. Combines the propensity score and outcome models. Consistent if either model is correctly specified.
When lagged_outcome_cov = FALSE and xformula = ~1, all
three methods reduce to a simple distribution comparison within each
(g,t) cell, which is consistent under unconditional unconfoundedness.
The ATT analogue (without the QTT) for staggered adoption under lagged-outcome unconfoundedness is developed in Callaway (2023).
Usage
lou_qtt(
yname,
gname,
tname,
idname = NULL,
data,
xformula = ~1,
lagged_outcome_cov = TRUE,
est_method = c("ipw", "or", "aipw"),
panel = TRUE,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
gt_type = c("att", "qtt"),
probs = NULL
)
Arguments
yname |
Name of the outcome variable in |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable. Required when
|
data |
A data frame. |
xformula |
One-sided formula for additional covariates used in the
propensity score and/or outcome model. Default |
lagged_outcome_cov |
Logical; if |
est_method |
Estimation method: |
panel |
Logical; |
weightsname |
Name of the column in |
control_group |
Which units to use as the comparison group:
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level for confidence intervals. Default |
cband |
Logical; if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of clusters for parallel bootstrap. Default |
gt_type |
Type of group-time effect to compute. |
probs |
For |
Value
For gt_type = "att", a pte_emp_boot object. For
gt_type = "qtt", a pte_qtt object with overall,
group-specific, and dynamic QTT curves, bootstrap standard errors,
and pointwise and uniform confidence bands.
References
Callaway, Brantly. “Policy Evaluation during a Pandemic.” Journal of Econometrics 236(2), 2023.
Melly, Blaise. “Estimation of Counterfactual Distributions Using Quantile Regression.” Working paper, University of St. Gallen, 2006.
Chernozhukov, Victor, Ivan Fernandez-Val, and Blaise Melly. “Inference on Counterfactual Distributions.” Econometrica 81(6), pp. 2205–2268, 2013.
See Also
unc_qte for the cross-sectional (non-staggered)
version. cic, qdid, mdid for
alternative identification strategies with staggered adoption.
Examples
data(mpdta, package = "did")
## ATT under lagged-outcome unconfoundedness (IPW with pre-period outcome)
res_att <- lou_qtt(
yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
lagged_outcome_cov = TRUE, est_method = "ipw",
gt_type = "att", biters = 20
)
summary(res_att)
## QTT with doubly-robust estimation
res_qtt <- lou_qtt(
yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
lagged_outcome_cov = TRUE, est_method = "aipw",
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20
)
summary(res_qtt)
Mean Difference-in-Differences
Description
Computes Quantile Treatment effects on the Treated (QTT) and the Average Treatment Effect on the Treated (ATT) using the Mean Difference-in-Differences identification strategy. Handles two-period data and staggered treatment adoption uniformly. Supports both panel and repeated cross sections data.
Identification. MDiD assumes the counterfactual distribution of
untreated potential outcomes is a location shift of the treated group's
pre-treatment distribution. The size of the shift is the mean DiD
\Delta = E[Y_{\text{post}}|D=0] - E[Y_{\text{pre}}|D=0], so
Q_{Y(0),\text{post}|D=1}(\tau) = Q_{Y,\text{pre}|D=1}(\tau) + \Delta.
This is stronger than parallel trends in means alone: it additionally
requires that the shape of the treated group's outcome distribution is
unchanged in the counterfactual. MDiD is a special case of QDiD that
applies a single mean shift rather than a rank-specific distributional
shift.
Covariate adjustment. When xformula is specified, the
scalar shift is replaced by a unit-specific conditional mean shift
\Delta(X_i) = E[Y_{\text{post}}|D=0,X_i] - E[Y_{\text{pre}}|D=0,X_i],
estimated by weighted OLS. The counterfactual for treated unit i is
Y_{\text{pre},i} + \Delta(X_i), and the unconditional counterfactual
distribution is the empirical CDF of these values. By the law of iterated
expectations, this consistently estimates F_{Y(0),\text{post}|D=1}.
Usage
mdid(
yname,
gname,
tname,
idname = NULL,
data,
panel = TRUE,
xformula = ~1,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
ret_quantile = NULL,
gt_type = "att",
probs = NULL
)
Arguments
yname |
Name of the outcome variable in |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable. Required when
|
data |
A data frame. |
panel |
Logical; |
xformula |
One-sided formula for covariates. Default |
weightsname |
Name of the column in |
control_group |
Which units to use as the comparison group:
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level for confidence bands. Default |
cband |
Logical; if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of clusters for parallel computation. Default |
ret_quantile |
Passed through to |
gt_type |
Type of group-time effect to compute. |
probs |
For |
Value
For gt_type = "att", a pte_results object from
ptetools. For gt_type = "qtt", a pte_qtt object
with overall, group-specific, and dynamic QTT curves and bootstrap SEs.
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
Thuysbaert, Bram. “Distributional Comparisons in Difference in Differences Models.” Working Paper, 2007.
Examples
data(mpdta, package = "did")
## ATT aggregated across all groups and periods
res_att <- mdid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "att", biters = 20)
summary(res_att)
## Full QTT curve at selected quantiles
res_qtt <- mdid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20)
summary(res_qtt)
Mean Difference-in-Differences: group-time estimator
Description
Computes the MDiD ATT and counterfactual outcome distribution
for a single 2x2 (pre/post x treated/control) data subset. Serves
directly as the attgt_fun argument to ptetools::pte. Panel
vs. repeated cross sections is detected automatically from whether the
same unit ids appear in both periods.
Identification. MDiD assumes that the counterfactual distribution of untreated potential outcomes for the treated group in the post period is a location shift of the treated group's pre-period distribution:
F_{Y(0),\text{post}|D=1}(y) = F_{Y,\text{pre}|D=1}(y - \Delta)
where \Delta = E[Y_{\text{post}}|D=0] - E[Y_{\text{pre}}|D=0] is
the mean DiD (the change in mean outcomes for the untreated group). The
counterfactual quantile function is therefore
Q_{Y(0),\text{post}|D=1}(\tau) = Q_{Y,\text{pre}|D=1}(\tau) + \Delta.
Covariate adjustment. With covariates, the scalar shift \Delta
is replaced by a unit-specific conditional mean shift
\Delta(X_i) = E[Y_{\text{post}}|D=0, X_i] - E[Y_{\text{pre}}|D=0, X_i],
estimated by weighted OLS on the control group in each period. The
counterfactual for treated pre-period unit i is
Y_{\text{pre},i} + \Delta(X_i). The unconditional counterfactual
distribution is the empirical CDF of these shifted values, which by the
law of iterated expectations consistently estimates
F_{Y(0),\text{post}|D=1}(y) = \int F_{Y,\text{pre}|D=1,X=x}(y - \Delta(x))\,dF_{X|D=1}(x).
Usage
mdid_gt(gt_data, xformula = ~1, ...)
Arguments
gt_data |
A data frame (typically a |
xformula |
One-sided formula for covariates. Default |
... |
Additional arguments passed through by |
Value
A ptetools::attgt_noif object with the ATT estimate and, in
extra_gt_returns, three objects: F1 (weighted ECDF of
observed treated outcomes in the post period), F0 (weighted ECDF
of counterfactual untreated outcomes for the treated group), and Fte
(weighted ECDF of individual treatment effects; NULL for repeated
cross sections).
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
Thuysbaert, Bram. “Distributional Comparisons in Difference in Differences Models.” Working Paper, 2007.
panel.checks
Description
Validates that the panel data structure is compatible with the panel estimators in the qte package. Specifically: checks that the treated group composition is constant across all time periods, warns if covariates appear to vary over time, and stops with an informative message if the treated group is empty or changes.
Usage
panel.checks(qp)
Arguments
qp |
QTEparams object |
Value
Invisibly returns NULL. Called for its side effects
(warnings and errors).
panel.qtet
Description
Deprecated. Use panel_qtt instead.
panel_qtt supports staggered treatment adoption and exposes the
pre_copula option for controlling how the copula is transferred
across pre-treatment periods.
panel.qtet computes the Quantile Treatment Effect
on the Treated (QTET) using the method of Callaway and Li (2015). This
method should be used when the researcher wants to invoke a Difference
in Differences assumption to identify the QTET. Relative to the other
Difference in Differences methods available in the qte package,
this method's assumptions are more intuitively similar to the identifying
assumptions used in identifying the Average Treatment Effect on the Treated
(ATT).
Additionally, this method can accommodate covariates in a more
flexible way than the other Difference in Differences methods available.
In order to accommodate covariates, the user should specify a vector x
of covariate names. The user also may specify a method for estimating
the propensity score. The default is logit.
panel.qtet can only be used in some situations, however. The
method requires three periods of panel data where individuals
are not treated until the last period. The data should be formatted
as a panel; the names of columns containing time periods and ids
for each cross sectional unit need to be passed to the method.
Usage
panel.qtet(
formla,
xformla = NULL,
t,
tmin1,
tmin2,
tname,
data,
idname,
probs = seq(0.05, 0.95, 0.05),
iters = 100,
alp = 0.05,
method = c("qr", "pscore"),
se = TRUE,
retEachIter = FALSE,
pl = FALSE,
cores = NULL,
biters = NULL,
cl = NULL
)
Arguments
formla |
The formula y ~ d where y is the outcome and d is the treatment indicator (d should be binary), d should be equal to one in all time periods for individuals that are eventually treated |
xformla |
A optional one sided formula for additional covariates that will be adjusted for. E.g ~ age + education. Additional covariates can also be passed by name using the x paramater. |
t |
The 3rd time period in the sample. Treated individuals should be treated in this time period and untreated individuals should not be treated. The code attempts to enforce this condition, but it is good try to handle this outside the panel.qtet method. |
tmin1 |
The 2nd time period in the sample. This should be a pre-treatment period for all individuals in the sample. |
tmin2 |
The 1st time period in the sample. This should be a pre-treatment period for all individuals in the sample. |
tname |
The name of the column containing the time periods |
data |
A data.frame containing all the variables used |
idname |
The individual (cross-sectional unit) id name |
probs |
A vector of values between 0 and 1 to compute the QTET at |
iters |
The number of iterations to compute bootstrap standard errors. This is only used if se=TRUE |
alp |
The significance level used for constructing bootstrap confidence intervals |
method |
The method for including covariates, should either be "QR" for quantile regression or "pscore" for propensity score |
se |
Boolean whether or not to compute standard errors |
retEachIter |
Boolean whether or not to return list of results from each iteration of the bootstrap procedure (default is FALSE). This is potentially useful for debugging but can cause errors due to running out of memory. |
pl |
Whether or not to compute standard errors in parallel |
cores |
Number of cores to use if computing in parallel |
biters |
Number of bootstrap iterations; alias for |
cl |
Number of cores for parallel bootstrap; alias for
|
Value
QTE object
References
Callaway, Brantly and Tong Li. “Quantile Treatment Effects in Difference in Differences Models with Panel Data.” Working Paper, 2019.
See Also
panel_qtt for the modern replacement supporting
staggered adoption.
Examples
# See ?panel_qtt for the modern replacement.
## Not run:
data(lalonde)
## Run the panel.qtet method on the experimental data with no covariates
pq1 <- panel.qtet(re ~ treat,
t = 1978, tmin1 = 1975, tmin2 = 1974, tname = "year",
data = lalonde.exp.panel, idname = "id", se = FALSE,
probs = seq(0.05, 0.95, 0.05)
)
summary(pq1)
## Run the panel.qtet method on the observational data with no covariates
pq2 <- panel.qtet(re ~ treat,
t = 1978, tmin1 = 1975, tmin2 = 1974, tname = "year",
data = lalonde.psid.panel, idname = "id", se = FALSE,
probs = seq(0.05, 0.95, 0.05)
)
summary(pq2)
## Run the panel.qtet method on the observational data conditioning on
## age, education, black, hispanic, married, and nodegree.
## The propensity score will be estimated using the default logit method.
pq3 <- panel.qtet(re ~ treat,
t = 1978, tmin1 = 1975, tmin2 = 1974, tname = "year",
xformla = ~ age + I(age^2) + education + black + hispanic + married + nodegree,
data = lalonde.psid.panel, idname = "id", se = FALSE, method = "pscore",
probs = seq(0.05, 0.95, 0.05)
)
summary(pq3)
pq4 <- panel.qtet(re ~ treat,
t = 1978, tmin1 = 1975, tmin2 = 1974, tname = "year",
xformla = ~ age + I(age^2) + education + black + hispanic + married + nodegree,
data = lalonde.psid.panel, idname = "id", se = FALSE, method = "qr",
probs = seq(0.05, 0.95, 0.05)
)
summary(pq4)
## End(Not run)
Panel QTT (Callaway-Li 2019)
Description
Computes Quantile Treatment Effects on the Treated (QTT) and
the Average Treatment Effect on the Treated (ATT) using the three-period
panel identification strategy of Callaway and Li (2019). Handles
two-period (one post + two pre-treatment periods) and staggered treatment
adoption via ptetools. Requires panel data for both groups.
Identification. Under a copula stability assumption and
distributional parallel trends on changes, the counterfactual distribution
F_{Y(0)^{\text{post}}|D=1} is recovered from three periods of panel
data without requiring rank invariance.
pre_copula. Controls which pre-treatment periods are used as the copula-transfer base for post-treatment cells (g, g+e):
"long"(default)pre2 = 2*(g - anticipation) - (g+e) - 2, matching the copula window to the event horizon e. Cells where pre2 does not exist in the data are excluded from aggregation with two-step weight renormalization.
"short"pre2 = g - anticipation - 2, always anchored at treatment onset.
Pre-test placebo cells always use the sliding base regardless of
pre_copula.
Usage
panel_qtt(
yname,
gname,
tname,
idname,
data,
xformula = ~1,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
gt_type = "att",
probs = NULL,
pre_copula = "long"
)
Arguments
yname |
Name of the outcome variable. |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable (required). |
data |
A data frame. |
xformula |
One-sided formula for covariates. Default |
weightsname |
Name of the sampling weights column. Default |
control_group |
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level. Default |
cband |
Logical; uniform confidence band if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of parallel clusters. Default |
gt_type |
|
probs |
Quantile grid for |
pre_copula |
|
Value
For gt_type = "att", a pte_emp_boot object. For
gt_type = "qtt", a pte_qtt object.
References
Callaway, Brantly and Tong Li. “Quantile Treatment Effects in Difference-in-Differences Models with Panel Data.” Quantitative Economics 10(4), pp. 1579-1618, 2019.
See Also
Examples
data(mpdta, package = "did")
## Panel QTT with rolling pre-period copula (default pre_copula = "long")
res <- panel_qtt(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20)
summary(res)
Panel QTT: group-time estimator (Callaway-Li 2019)
Description
Computes the panel QTT and counterfactual outcome distribution
for a single (g,t) cell using the three-period copula-stability estimator
of Callaway and Li (2019). Serves directly as the attgt_fun
argument to ptetools::pte.
Identification. Under copula stability
C(F_{Y^{\text{pre2}}|D=1},\, F_{\Delta Y^{\text{pre}}|D=1}) =
C(F_{Y^{\text{pre1}}(0)|D=1},\, F_{\Delta Y^{\text{post}}(0)|D=1})
and distributional parallel trends on changes
F_{\Delta Y^{\text{post}}(0)|D=1} = F_{\Delta Y^{\text{ctrl}}}
the counterfactual outcome for each treated unit i is
kcf_i = L_i + C_i,
where L_i = Q_{Y^{\text{pre1}}|D=1}(u_i) is the treated pre1
quantile at rank u_i = F_{Y^{\text{pre2}}|D=1}(Y^{\text{pre2}}_i)
(the Rosenblatt transform), and
C_i = Q_{\Delta Y^{\text{ctrl}}}(v_i) is the control change at rank
v_i = F_{\Delta Y^{\text{pre}}|D=1}(\Delta Y^{\text{pre}}_i).
The goal is distributional: \{kcf_i\} is a sample from
F_{Y(0)^{\text{post}}|D=1}, not individual counterfactuals.
Panel data required for both groups. Three periods for treated (pre2, pre1, post) and two for control (pre1, post).
Usage
panel_qtt_gt(gt_data, xformula = ~1, ...)
Arguments
gt_data |
A |
xformula |
One-sided formula for covariates. Default |
... |
Additional arguments passed through by |
Value
A ptetools::attgt_noif object with att and, in
extra_gt_returns, F0 (counterfactual ECDF), F1
(observed post ECDF), and Fte (individual-effect ECDF).
References
Callaway, Brantly and Tong Li. “Quantile Treatment Effects in Difference-in-Differences Models with Panel Data.” Quantitative Economics 10(4), pp. 1579-1618, 2019.
QTT Aggregation for pre_copula = "long"
Description
Custom aggte_fun for ptetools::pte that
handles the two-step weight renormalization needed when
pre_copula = "long": some (g,t) cells are structurally
uncomputable (their pre2 does not exist in the data), and those cells
must be excluded from aggregation with proper weight redistribution.
Two-step weights (overall):
Identify surviving groups (those with at least one valid post-treatment cell); renormalize
p_gamong those groups only.Within each surviving group, assign equal weight
p_g / |\text{valid cells for } g|to each valid post-treatment cell.
Dynamic (event-study) weights: for each event time e, renormalize
p_g among groups where (g, g+e) is valid.
Error behaviour: if a structurally valid cell returns NA
att, the function errors immediately — such NAs indicate a bug in
panel_qtt_gt, not a structural limitation.
Usage
panel_qtt_long_agg(attgt.list, ptep, extra_gt_returns)
Arguments
attgt.list |
List of per-cell attgt results from |
ptep |
ptetools parameter environment. |
extra_gt_returns |
List of per-cell extra returns (F0, F1, Fte ECDFs). |
Value
A list with overall_results, dyn_results,
group_results, attgt_results, F0_overall,
F1_overall — matching the structure returned by
ptetools::qtt_pte_aggregations.
panelize.data
Description
get data in correct format for using panel methods in qte package
Usage
panelize.data(data, idname, tname, t, tmin1, tmin2 = NULL)
Arguments
data |
A data.frame containing all the variables used |
idname |
The individual (cross-sectional unit) id name |
tname |
The name of the column containing the time periods |
t |
The 3rd time period in the sample. Treated individuals should be treated in this time period and untreated individuals should not be treated. The code attempts to enforce this condition, but it is good try to handle this outside the panel.qtet method. |
tmin1 |
The 2nd time period in the sample. This should be a pre-treatment period for all individuals in the sample. |
tmin2 |
The 1st time period in the sample. This should be a pre-treatment period for all individuals in the sample. |
Value
data.frame
plot.QTE
Description
Plots a QTE object using autoplot.QTE.
Usage
## S3 method for class 'QTE'
plot(x, cband = TRUE, ylab = "QTE", ...)
Arguments
x |
a |
cband |
logical; if |
ylab |
label for the y-axis. Default |
... |
passed to |
Value
invisibly returns the ggplot object.
Print summary.QTE
Description
Prints a summary.QTE object.
Usage
## S3 method for class 'summary.QTE'
print(x, ...)
Arguments
x |
A |
... |
unused. |
Value
None. Called for its side effect of printing.
Quantile Difference-in-Differences
Description
Computes Quantile Treatment effects on the Treated (QTT) and the Average Treatment Effect on the Treated (ATT) using the Quantile Difference-in-Differences identification strategy of Athey and Imbens (2006). Handles two-period data and staggered treatment adoption uniformly. Supports both panel and repeated cross sections data.
Usage
qdid(
yname,
gname,
tname,
idname = NULL,
data,
panel = TRUE,
xformula = ~1,
weightsname = NULL,
control_group = "notyettreated",
anticipation = 0,
alp = 0.05,
cband = TRUE,
biters = 100,
cl = 1,
ret_quantile = NULL,
gt_type = "att",
probs = NULL
)
Arguments
yname |
Name of the outcome variable in |
gname |
Name of the treatment group variable (first treatment period; 0 for never-treated units). |
tname |
Name of the time period variable. |
idname |
Name of the unit id variable. Required when
|
data |
A data frame. |
panel |
Logical; |
xformula |
One-sided formula for covariates used in the covariate
adjustment. Default |
weightsname |
Name of the column in |
control_group |
Which units to use as the comparison group:
|
anticipation |
Number of periods of anticipation. Default |
alp |
Significance level for confidence bands. Default |
cband |
Logical; if |
biters |
Number of bootstrap iterations. Default |
cl |
Number of clusters for parallel computation. Default |
ret_quantile |
Passed through to |
gt_type |
Type of group-time effect to compute. |
probs |
For |
Value
For gt_type = "att", a pte_results object from
ptetools. For gt_type = "qtt", a pte_qtt object
with overall, group-specific, and dynamic QTT curves and bootstrap SEs.
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
Examples
data(mpdta, package = "did")
## ATT aggregated across all groups and periods
res_att <- qdid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "att", biters = 20)
summary(res_att)
## Full QTT curve at selected quantiles
res_qtt <- qdid(yname = "lemp", gname = "first.treat", tname = "year",
idname = "countyreal", data = mpdta,
gt_type = "qtt", probs = seq(0.1, 0.9, 0.1), biters = 20)
summary(res_qtt)
Quantile Difference-in-Differences: group-time estimator
Description
Computes the QDiD ATT and counterfactual outcome distribution
for a single 2x2 (pre/post x treated/control) data subset. Serves
directly as the attgt_fun argument to ptetools::pte. Panel
vs. repeated cross sections is detected automatically from whether the
same unit ids appear in both periods.
Usage
qdid_gt(gt_data, xformula = ~1, ...)
Arguments
gt_data |
A data frame (typically a |
xformula |
One-sided formula for covariates. Default |
... |
Additional arguments passed through by |
Value
A ptetools::attgt_noif object with the ATT estimate and, in
extra_gt_returns, three objects: F1 (weighted ECDF of
observed treated outcomes in the post period), F0 (weighted ECDF
of counterfactual untreated outcomes for the treated group), and Fte
(weighted ECDF of individual treatment effects; NULL for repeated
cross sections).
References
Athey, Susan and Guido Imbens. “Identification and Inference in Nonlinear Difference-in-Differences Models.” Econometrica 74(2), pp. 431-497, 2006.
setupData
Description
setupData extracts treated/untreated subsets, ECDFs,
and auxiliary vectors from a QTEparams object and injects them
into the caller's environment via assign(..., envir=parent.frame()).
This side-effectful pattern is intentional — all compute.* functions
rely on the variables created here being available in their local scope.
Usage
setupData(qteParams)
Arguments
qteParams |
A |
Value
Invisibly returns NULL. The function's effect is the
assignment of data objects into the calling environment.
Summary
Description
summary.QTE summarizes a QTE object, returning
formatted data frames for the overall ATE and the QTE table suitable for
printing.
Usage
## S3 method for class 'QTE'
summary(object, ...)
Arguments
object |
A |
... |
unused. |
Value
A summary.QTE object (a list with overall_ate and
qte_table data frames).
Three-Period Subset for Panel QTT
Description
Custom subset_fun for ptetools::pte that pulls
three time periods for each (g,t) cell: pre2, pre1 = g - anticipation - 1,
and post = tp. How pre2 is chosen depends on pre_copula:
"long"(default)pre2 = 2*(g - anticipation) - tp - 2, so the copula-transfer window matches the event horizon e = tp - (g - anticipation). Cells where this pre2 does not exist in the data return empty data and
panel_qtt_gtreturnsNA."short"pre2 = g - anticipation - 2 (fixed at treatment onset regardless of e).
For pre-treatment placebo cells (tp < g - anticipation), the base
always slides backwards regardless of pre_copula:
pre2 = tp - 2, pre1 = tp - 1. panel_qtt() sets
required_pre_periods = 2 so that the minimum tp in tlist
is the third period, guaranteeing tp - 2 is always a valid period.
Usage
three_period_subset(
data,
g,
tp,
control_group = "notyettreated",
anticipation = 0,
pre_copula = "long",
...
)
Arguments
data |
A data frame prepared by |
g |
The current group (first treatment period). |
tp |
The current time period. |
control_group |
|
anticipation |
Number of periods of anticipation. Default |
pre_copula |
|
... |
Additional arguments; silently ignored. |
Value
A list with elements gt_data, n1, disidx.
unc_qte
Description
Estimates the Quantile Treatment Effect (QTE) or Quantile
Treatment Effect on the Treated (QTT) under unconfoundedness, also known
as selection on observables. The key identifying assumption is
(Y(0), Y(1)) \perp D \mid X, i.e., potential outcomes are
independent of treatment conditional on covariates X.
Three estimation methods are available via est_method:
"ipw"Propensity-score reweighting (Firpo 2007). The propensity score
p(X) = P(D=1|X)is estimated by logit or probit and used to reweight the sample so that the covariate distributions of the treated and untreated groups match. For the QTE, both groups are reweighted toward the population distribution; for the QTT, only the untreated group is reweighted toward the treated covariate distribution."or"Outcome regression via quantile regression inversion.
rqis fit on a dense internal grid of\tauvalues, yielding a conditional quantile functionQ_{Y|X,D=j}(\tau)for each armj. The marginal distribution is recovered by averaging conditional quantile functions over the empirical covariate distribution (Melly 2006; Chernozhukov, Fernandez-Val, and Melly 2013)."aipw"Doubly-robust augmented IPW. Combines the propensity score model with the conditional quantile outcome model. The CDF estimator is consistent if either the propensity score or the outcome model is correctly specified (semiparametric efficiency when both are correct).
When xformla = ~1 (the default), all three methods reduce to
simple quantile differences between the treated and untreated groups, which
is consistent under unconditional unconfoundedness. Covariates are required
for covariate-adjusted estimation.
Standard errors and uniform confidence bands are computed via the
empirical bootstrap. Setting biters = 0 is planned for a future
version to skip inference and return point estimates only.
Usage
unc_qte(
yname,
dname,
data,
xformla = ~1,
weightsname = NULL,
probs = seq(0.05, 0.95, 0.05),
alp = 0.05,
biters = 100,
cband = TRUE,
boot_type = "empirical",
method = c("logit", "probit"),
est_method = c("ipw", "or", "aipw"),
target = c("qte", "qtt"),
cl = 1
)
Arguments
yname |
character; name of the outcome variable in |
dname |
character; name of the binary treatment indicator in
|
data |
data.frame containing the analysis data. |
xformla |
one-sided formula for covariates used in the propensity
score and/or outcome model, e.g. |
weightsname |
character; name of a column in |
probs |
numeric vector of quantile levels at which to evaluate the
QTE or QTT. Default |
alp |
significance level for confidence intervals. Default 0.05. |
biters |
number of bootstrap iterations for standard errors and confidence bands. Default 100. |
cband |
logical; if |
boot_type |
bootstrap variant. Currently only |
method |
propensity score link function: |
est_method |
estimation method; one of:
|
target |
target parameter; one of:
|
cl |
number of cores for parallel bootstrap. Default 1 (sequential). |
Value
An object of class QTE containing:
qtenumeric vector of estimated QTE (or QTT) at each element of
probs.ateestimated ATE (or ATT when
target = "qtt").qte.sebootstrap standard errors for
qte.qte.lower,qte.upperconfidence interval bounds for
qte; uniform whencband = TRUE, pointwise otherwise.ate.se,ate.lower,ate.upperSE and CI for
ate.probsthe
probsvector passed by the user.pscore.regfitted propensity score
glmobject, orNULLwhenest_method = "or"orxformla = ~1.
Use summary() to print a formatted table and plot() to
display the QTE curve with confidence bands.
References
Firpo, Sergio. “Efficient Semiparametric Estimation of Quantile Treatment Effects.” Econometrica 75(1), pp. 259–276, 2007.
Melly, Blaise. “Estimation of Counterfactual Distributions Using Quantile Regression.” Working paper, University of St. Gallen, 2006.
Chernozhukov, Victor, Ivan Fernandez-Val, and Blaise Melly. “Inference on Counterfactual Distributions.” Econometrica 81(6), pp. 2205–2268, 2013.
Examples
data(lalonde)
## IPW, no covariates (simple quantile differences)
q1 <- unc_qte(yname = "re78", dname = "treat", data = lalonde.psid,
biters = 20, probs = seq(0.05, 0.95, 0.05))
summary(q1)
plot(q1)
## OR with covariates, QTE
xf <- ~ age + I(age^2) + education + black + hispanic + married + nodegree
q2 <- unc_qte(yname = "re78", dname = "treat", data = lalonde.psid,
xformla = xf, est_method = "or",
biters = 20, probs = seq(0.05, 0.95, 0.05))
summary(q2)
## AIPW with covariates, QTT
q3 <- unc_qte(yname = "re78", dname = "treat", data = lalonde.psid,
xformla = xf, est_method = "aipw", target = "qtt",
biters = 20, probs = seq(0.05, 0.95, 0.05))
summary(q3)
Weighted type-1 quantile
Description
Smallest y with weighted CDF >= p. Uses a small
numerical tolerance on the comparison so that a p landing exactly
on a floating-point rounding boundary (common with uniform weights, e.g.
1/n) picks the intended order statistic instead of flipping based
on last-bit differences in summation across platforms.
Usage
wquant(y_vec, w_vec, probs)
Arguments
y_vec |
numeric vector of values. |
w_vec |
numeric vector of weights, same length as |
probs |
numeric vector of probabilities in |
Value
numeric vector, same length as probs.