Panel preprocessing now excludes whole units with missing covariates or sampling weights before checking time invariance. Retained units remain matched by ID, and observed time-varying covariates or weights still fail.
Formula-based estimators preserve user columns named
y, D, post, or w
when extracting outcomes, weights, and covariates. Renaming a variable
no longer changes its meaning through internal preprocessing
columns.
Improved DR estimators now require a numerically verified
solution of the original exponential-IPT equations. Logit MLE is used
only for initialization; failed IPT fits stop and suggest explicitly
rerunning the traditional DR estimator. The secondary IPT candidate is
checked against the original equations even when its continued objective
reports convergence. The returned ps.flag identifies the
verified fitting route (0 or 1); value 2 is removed. Fitting normalizes
the common scale of weights to avoid scale-dependent optimizer stopping.
Numerically ill-conditioned designs are rejected. Every
weighted-bootstrap replicate must pass the same check, and failures stop
with the replicate number without skipping or redrawing the
fit.
The weighted bootstrap in drdid_imp_panel() now uses
the point estimator’s treated-weight denominator for its combined
residual contributions. This makes each draw refit the same implemented
statistic, including active trimming and supplied designs without an
intercept. Weighted-bootstrap draws, standard errors, and intervals can
change; point estimates, analytic inference, and multiplier inference
are unchanged.
IPT criteria now evaluate weighted nonlinear contributions without first creating avoidable overflowing or underflowing intermediate exponentials. Weighted values, gradients, and Hessians retain representable terms and reject unresolved opposing overflow terms. The original criteria and continuation rule are preserved. Fitting reuses fixed-data checks and avoids unnecessary exceptional arithmetic while retaining these safeguards.
Zero-weight rows no longer enter IPT objective, gradient, or Hessian arithmetic. Extreme finite covariates in those rows cannot create NaNs through zero times an overflowing intermediate value. The original objective divisor, model dimension, and secondary continuation threshold are preserved.
The IPT propensity-score fallback used by the improved DR
estimators now weights its full objective consistently with its gradient
and Hessian. This corrects optimization with unequal observation or
bootstrap weights when the primary trust fit does not
converge.
Sampling weights are checked before normalization; negative, nonfinite, all-zero, or incorrectly sized low-level weights now give a clear error. Legitimate zero weights and existing missing-data exclusion are preserved.
The weighted bootstrap in ipw_did_rc() now refits
the same statistic as the point estimator, including normalization of
the combined observation and bootstrap weights and the full-sample
pre/post time shares. Trimming affects comparison contributions, as in
the point estimator. Weighted bootstrap draws, standard errors, and
intervals can change; the original ATT, analytic inference, and
multiplier bootstrap are unchanged.
ipw_did_rc() now includes the effect of sample-mean
normalization of observation weights in its influence function and the
resulting analytic and multiplier-bootstrap inference under iid
sampling. The ATT point estimate is unchanged.
Bootstrap inference now returns a zero standard error and point interval when every centered bootstrap draw is exactly zero. Nonfinite draws or a zero IQR with nonzero draws stop with a clear error; no draws are removed or redrawn, and positive-scale inference retains its existing arithmetic.
twfe_did_panel() and twfe_did_rc() now
preserve matrix dimensions when removing a supplied intercept. An
intercept plus one covariate now fits the same regression as supplying
that covariate as a numeric vector or a matrix with one column, instead
of failing. Intercept-only inputs retain their existing no-covariate
behavior.
twfe_did_panel() now accounts for dependence between
each individual’s pre/post observations in its analytical standard
error. With covariates, the returned influence function now has one
value per individual instead of one per period row. This matches
individual-clustered sandwich inference without small-sample corrections
and the other panel estimators’ convention. The point estimate and both
bootstrap procedures are preserved, up to floating-point precision. The
no-covariate inference path is unchanged. Direct calls now reject
missing or mismatched individual inputs before fitting, preventing row
omission from breaking pre/post alignment.
Bootstrap estimation now rejects nboot values that
are not finite scalar integers of at least 2 before fitting or drawing
bootstrap weights. The low-level NULL default remains 999;
boot = FALSE continues to ignore it.
Panel preprocessing for drdid(),
ordid(), and ipwdid() now removes both
observations of a unit when either outcome is missing, matches pre/post
outcomes by individual ID, and checks group sizes after exclusions.
Previously, dropping individual rows with missing outcomes could
silently pair different individuals and produce incorrect point
estimates and standard errors. Warnings now report the number of
affected panel units.
drdid_rc() and drdid_rc1(): the
estimation effect of the pre-period outcome regression for the
comparison group now enters the influence function with the sign given
in Appendix B of Sant’Anna and Zhao (2020). It previously entered with
the opposite sign. Point estimates are unchanged. Analytic and
multiplier-bootstrap standard errors change. The two versions agree
asymptotically when the propensity score model is correctly specified,
but not when only the outcome regressions are.
Treatment indicators must use 0 for comparison and 1 for treated units. Invalid coding is rejected explicitly rather than silently changing weights.
The internal GLM fitter now rejects designs with fewer rows than
columns before entering fastglm. Such designs cannot have
full column rank. Callers receive an ordinary R error when a regression
cell is undersized; supported fits retain the same
calculations.
This release substantially speeds up the 2x2 estimators and tightens the handling of ill-conditioned designs. Point estimates, standard errors, and influence functions are unchanged up to floating-point precision (~1e-14).
The propensity-score and outcome regressions now use
fastglm’s low-level entry point (fastglmPure)
in place of the fastglm() wrapper, skipping the per-call
input-coercion and family/deviance bookkeeping that was paid on every
fit. This is applied throughout: the point estimators, every
weighted-bootstrap helper (which refits on each of nboot
iterations), and the IPT/calibration propensity initializer.
The influence-function computations use crossprod()
and BLAS dot products in place of colMeans(. * int.cov) and
t(int.cov) %*% (W * int.cov).
Together these make the 2x2 estimators roughly 1.5x faster, with the weighted bootstrap benefiting proportionally.
The propensity-score Hessian is now checked for singularity with
rcond() before inversion, matching the long-standing check
on the outcome-regression design. A near-singular propensity-score
design previously yielded a silently incorrect standard error; it now
stops with an informative message.
std_ipw_did_rc now warns when the propensity-score
estimation does not converge and stops when the estimated coefficients
are NA, matching the other propensity-score estimators
(these guards were previously missing, so a rank-deficient design
returned a corrupted standard error silently).
The repeated cross-section pre-processing now warns when collinear covariates are dropped, matching the panel pre-processing (previously the repeated cross-section path dropped them without notice).
Improve code to avoid redundant data checks
Use fastglm instead of parglm for improved speed
Restore solve as default to invert matrix, as it is faster than qr.solve for small matrices.
Improve error handling for non-invertible matrices.
Changing estimation methods for fastglm and parglm (in place of lm and glm).
Do not let the estimated propensity score be above 1 - 1e-6 (instead of 1 - e-16).
Speed up data processing using Rcpp
The weights are now enforced to be normalized and have mean 1 across all observations.
Use qr.solve as default (instead of solve)
Drop collinear variables in pre_process_drdid.R (useful in drdid command but not other commands)
Add compatibility with R 3.5
Improve invertibility of outcome regression design matrix
Add new flags for non-unique unit identifier
Better handle of factor variables as covariates
Allows for treating covariates as factor and alike when computing DiD
Improve error and warning handling due to collinearity and convergence issues.
First official version of package, functions for computing a variety of difference-in-differences (DiD) estimators for the ATT.
Documentation is improved compared to the devel version, including examples for every function now.
Created wrapper function drdid, ordid
and ipwdid to implement doubly-robust, outcome regression
and inverse probability weighted DID estimators.
Add dataset used in the empirical application of Sant’Anna and Zhao (2020).