Triple Difference (DDD) ======================= Triple Difference estimator for designs where treatment requires two criteria. This module implements the methodology from Ortiz-Villavicencio & Sant'Anna (2025), which correctly handles covariate adjustment in DDD designs. Unlike naive implementations that difference two DiDs, this approach provides valid estimates when identification requires conditioning on covariates. **When to use DDD instead of DiD:** DDD allows for violations of parallel trends that are: - Group-specific (e.g., economic shocks affecting treatment states) - Partition-specific (e.g., trends affecting women everywhere) As long as these biases are additive, DDD differences them out. The key assumption is that the *differential* trend between eligible and ineligible units would be the same across groups. **Reference:** Ortiz-Villavicencio, M., & Sant'Anna, P. H. C. (2025). Better Understanding Triple Differences Estimators. *Working Paper*. `arXiv:2505.09942 `_ .. module:: diff_diff.triple_diff TripleDifference ---------------- Main estimator class for Triple Difference designs. .. autoclass:: diff_diff.TripleDifference :no-index: :members: :undoc-members: :show-inheritance: :inherited-members: .. rubric:: Methods .. autosummary:: ~TripleDifference.fit ~TripleDifference.get_params ~TripleDifference.set_params TripleDifferenceResults ----------------------- Results container for Triple Difference estimation. .. autoclass:: diff_diff.TripleDifferenceResults :no-index: :members: :undoc-members: :show-inheritance: .. rubric:: Methods .. autosummary:: ~TripleDifferenceResults.summary ~TripleDifferenceResults.print_summary ~TripleDifferenceResults.to_dict ~TripleDifferenceResults.to_dataframe Convenience Function -------------------- .. autofunction:: diff_diff.triple_difference Estimation Methods ------------------ The estimator supports three estimation methods: .. list-table:: :header-rows: 1 :widths: 15 35 50 * - Method - Description - When to use * - ``"dr"`` - Doubly robust - Recommended. Consistent if either outcome or propensity model is correct * - ``"reg"`` - Regression adjustment - Simple outcome regression with full interactions * - ``"ipw"`` - Inverse probability weighting - When propensity score model is well-specified Example Usage ------------- Basic usage:: from diff_diff import TripleDifference ddd = TripleDifference(estimation_method='dr') results = ddd.fit( data, outcome='wages', group='policy_state', # 1=state enacted policy, 0=control state partition='female', # 1=women (affected by policy), 0=men time='post' # 1=post-policy, 0=pre-policy ) results.print_summary() With covariates:: results = ddd.fit( data, outcome='wages', group='policy_state', partition='female', time='post', covariates=['age', 'education', 'experience'] ) Using the convenience function:: from diff_diff import triple_difference results = triple_difference( data, outcome='wages', group='policy_state', partition='female', time='post', estimation_method='dr' )