Skip to main content
Ctrl+K

diff-diff

  • Practitioner Guide
  • Decision Tree
  • Getting Started
  • Estimator Guide
  • Troubleshooting
    • References
    • Measuring Campaign Impact on Brand Awareness with Survey Data
    • Tutorial 18: Geo-Experiment Analysis with SyntheticDiD
    • Tutorial 19: dCDH for Marketing Pulse Campaigns
    • Tutorial 20: HAD for a National Brand Campaign with Regional Spend Intensity
    • Tutorial 21: HAD Pre-test Workflow - Running the Pre-test Diagnostics on the Brand Campaign Panel
    • Tutorial 22: Survey-Weighted HAD - The BRFSS-Shape Rollout
    • Spillover-aware DiD with SpilloverDiD — a TVA-style worked example
    • Basic Difference-in-Differences with diff-diff
    • Staggered Difference-in-Differences
    • Synthetic Difference-in-Differences (SDID)
    • Tutorial 8: Triple Difference (DDD) Estimation
    • Real-World Data Examples
    • Triply Robust Panel (TROP) Estimator
    • Imputation DiD (Borusyak, Jaravel & Spiess 2024)
    • Two-Stage DiD (Gardner 2022)
    • Stacked DiD (Wing, Freedman & Hollingsworth 2024)
    • Continuous Difference-in-Differences
    • Efficient DiD (Chen, Sant’Anna & Xie 2025)
    • Survey-Aware Difference-in-Differences
    • Wooldridge Extended Two-Way Fixed Effects (ETWFE)
    • Testing Parallel Trends and DiD Diagnostics
    • Honest DiD: Sensitivity Analysis for Parallel Trends
    • Power Analysis for Difference-in-Differences
    • Pre-Trends Power Analysis (Roth 2022)
    • Tutorial 24: Staggered Rollout or a Simple 2×2? A Power-Analysis Decision Guide
    • R Comparison
    • Python Comparison
    • Benchmarks
    • API Reference
  • GitHub
  • PyPI
  • Practitioner Guide
  • Decision Tree
  • Getting Started
  • Estimator Guide
  • Troubleshooting
  • References
  • Measuring Campaign Impact on Brand Awareness with Survey Data
  • Tutorial 18: Geo-Experiment Analysis with SyntheticDiD
  • Tutorial 19: dCDH for Marketing Pulse Campaigns
  • Tutorial 20: HAD for a National Brand Campaign with Regional Spend Intensity
  • Tutorial 21: HAD Pre-test Workflow - Running the Pre-test Diagnostics on the Brand Campaign Panel
  • Tutorial 22: Survey-Weighted HAD - The BRFSS-Shape Rollout
  • Spillover-aware DiD with SpilloverDiD — a TVA-style worked example
  • Basic Difference-in-Differences with diff-diff
  • Staggered Difference-in-Differences
  • Synthetic Difference-in-Differences (SDID)
  • Tutorial 8: Triple Difference (DDD) Estimation
  • Real-World Data Examples
  • Triply Robust Panel (TROP) Estimator
  • Imputation DiD (Borusyak, Jaravel & Spiess 2024)
  • Two-Stage DiD (Gardner 2022)
  • Stacked DiD (Wing, Freedman & Hollingsworth 2024)
  • Continuous Difference-in-Differences
  • Efficient DiD (Chen, Sant’Anna & Xie 2025)
  • Survey-Aware Difference-in-Differences
  • Wooldridge Extended Two-Way Fixed Effects (ETWFE)
  • Testing Parallel Trends and DiD Diagnostics
  • Honest DiD: Sensitivity Analysis for Parallel Trends
  • Power Analysis for Difference-in-Differences
  • Pre-Trends Power Analysis (Roth 2022)
  • Tutorial 24: Staggered Rollout or a Simple 2×2? A Power-Analysis Decision Guide
  • R Comparison
  • Python Comparison
  • Benchmarks
  • API Reference
  • GitHub
  • PyPI

Section Navigation

  • diff_diff.DifferenceInDifferences
  • diff_diff.TwoWayFixedEffects
  • diff_diff.MultiPeriodDiD
  • diff_diff.SyntheticDiD
  • diff_diff.CallawaySantAnna
  • diff_diff.ChaisemartinDHaultfoeuille
  • diff_diff.SunAbraham
  • diff_diff.ImputationDiD
  • diff_diff.StackedDiD
  • diff_diff.TripleDifference
  • diff_diff.TROP
  • diff_diff.SyntheticControl
  • diff_diff.ContinuousDiD
  • diff_diff.HeterogeneousAdoptionDiD
  • diff_diff.EfficientDiD
  • diff_diff.TwoStageDiD
  • diff_diff.SpilloverDiD
  • diff_diff.WooldridgeDiD
  • diff_diff.BaconDecomposition
  • diff_diff.StaggeredTripleDifference
  • diff_diff.DiDResults
  • diff_diff.MultiPeriodDiDResults
  • diff_diff.SyntheticDiDResults
  • diff_diff.PeriodEffect
  • diff_diff.CallawaySantAnnaResults
  • diff_diff.CSBootstrapResults
  • diff_diff.GroupTimeEffect
  • diff_diff.ChaisemartinDHaultfoeuilleResults
  • diff_diff.DCDHBootstrapResults
  • diff_diff.SunAbrahamResults
  • diff_diff.SABootstrapResults
  • diff_diff.ImputationDiDResults
  • diff_diff.ImputationBootstrapResults
  • diff_diff.TripleDifferenceResults
  • diff_diff.StackedDiDResults
  • diff_diff.TROPResults
  • diff_diff.SyntheticControlResults
  • diff_diff.ContinuousDiDResults
  • diff_diff.DoseResponseCurve
  • diff_diff.HeterogeneousAdoptionDiDResults
  • diff_diff.HeterogeneousAdoptionDiDEventStudyResults
  • diff_diff.EfficientDiDResults
  • diff_diff.EDiDBootstrapResults
  • diff_diff.TwoStageDiDResults
  • diff_diff.TwoStageBootstrapResults
  • diff_diff.SpilloverDiDResults
  • diff_diff.BaconDecompositionResults
  • diff_diff.wooldridge_results.WooldridgeDiDResults
  • diff_diff.Comparison2x2
  • diff_diff.StaggeredTripleDiffResults
  • diff_diff.TWFEWeightsResult
  • diff_diff.plot_event_study
  • diff_diff.plot_group_effects
  • diff_diff.plot_sensitivity
  • diff_diff.plot_honest_event_study
  • diff_diff.plot_bacon
  • diff_diff.plot_power_curve
  • diff_diff.plot_pretrends_power
  • diff_diff.run_placebo_test
  • diff_diff.placebo_timing_test
  • diff_diff.placebo_group_test
  • diff_diff.permutation_test
  • diff_diff.leave_one_out_test
  • diff_diff.run_all_placebo_tests
  • diff_diff.PlaceboTestResults
  • diff_diff.profile_panel
  • diff_diff.PanelProfile
  • diff_diff.OutcomeShape
  • diff_diff.TreatmentDoseShape
  • diff_diff.Alert
  • diff_diff.HonestDiD
  • diff_diff.HonestDiDResults
  • diff_diff.SensitivityResults
  • diff_diff.DeltaSD
  • diff_diff.DeltaRM
  • diff_diff.DeltaSDRM
  • diff_diff.compute_honest_did
  • diff_diff.sensitivity_plot
  • diff_diff.check_parallel_trends
  • diff_diff.check_parallel_trends_robust
  • diff_diff.equivalence_test_trends
  • diff_diff.HADPretestReport
  • diff_diff.QUGTestResults
  • diff_diff.StuteTestResults
  • diff_diff.YatchewTestResults
  • diff_diff.StuteJointResult
  • diff_diff.wild_bootstrap_se
  • diff_diff.WildBootstrapResults
  • diff_diff.PowerAnalysis
  • diff_diff.PowerResults
  • diff_diff.SimulationPowerResults
  • diff_diff.SimulationMDEResults
  • diff_diff.SimulationSampleSizeResults
  • diff_diff.compute_power
  • diff_diff.compute_mde
  • diff_diff.compute_sample_size
  • diff_diff.simulate_power
  • diff_diff.simulate_mde
  • diff_diff.simulate_sample_size
  • diff_diff.PreTrendsPower
  • diff_diff.PreTrendsPowerResults
  • diff_diff.PreTrendsPowerCurve
  • diff_diff.compute_pretrends_power
  • diff_diff.compute_mdv
  • diff_diff.BusinessReport
  • diff_diff.BusinessContext
  • diff_diff.DiagnosticReport
  • diff_diff.DiagnosticReportResults
  • diff_diff.LocalLinearFit
  • diff_diff.BandwidthResult
  • diff_diff.BiasCorrectedFit
  • diff_diff.generate_did_data
  • diff_diff.generate_continuous_did_data
  • diff_diff.generate_staggered_data
  • diff_diff.generate_event_study_data
  • diff_diff.generate_ddd_data
  • diff_diff.generate_factor_data
  • diff_diff.generate_panel_data
  • diff_diff.make_treatment_indicator
  • diff_diff.make_post_indicator
  • diff_diff.wide_to_long
  • diff_diff.balance_panel
  • diff_diff.validate_did_data
  • diff_diff.summarize_did_data
  • diff_diff.create_event_time
  • diff_diff.aggregate_to_cohorts
  • diff_diff.rank_control_units
  • diff_diff.load_card_krueger
  • diff_diff.load_castle_doctrine
  • diff_diff.load_divorce_laws
  • diff_diff.load_mpdta
  • diff_diff.load_dataset
  • diff_diff.list_datasets
  • diff_diff.clear_cache
  • Estimators
  • Staggered Adoption
  • de Chaisemartin-D’Haultfœuille (dCDH) DiD
  • Imputation DiD (Borusyak et al. 2024)
  • Stacked Difference-in-Differences
  • Triple Difference (DDD)
  • Triply Robust Panel (TROP)
  • Synthetic Control Method (SCM)
  • Continuous Difference-in-Differences
  • Heterogeneous Adoption Difference-in-Differences
  • Efficient Difference-in-Differences
  • Two-Stage DiD (Gardner 2022)
  • Spillover-Aware DiD (Butts 2021)
  • Wooldridge Extended Two-Way Fixed Effects (ETWFE)
  • Bacon Decomposition (Goodman-Bacon 2021)
  • Local-Linear Infrastructure
  • Panel Profiling
  • Diagnostics
  • Honest DiD
  • Power Analysis
  • Pre-Trends Power Analysis
  • BusinessReport
  • DiagnosticReport
  • Results Classes
  • Visualization
  • Utilities
  • Data Preparation
  • Datasets
  • API Reference
  • diff_diff.check_parallel_trends_robust

diff_diff.check_parallel_trends_robust#

diff_diff.check_parallel_trends_robust(data, outcome, time, treatment_group, unit=None, pre_periods=None, n_permutations=1000, seed=None, wasserstein_threshold=0.2)[source]

Perform robust parallel trends testing using distributional comparisons.

Uses the Wasserstein (Earth Mover’s) distance to compare the full distribution of outcome changes between treated and control groups, with permutation-based inference.

Parameters:
  • data (pd.DataFrame) – Panel data with repeated observations over time.

  • outcome (str) – Name of outcome variable column.

  • time (str) – Name of time period column.

  • treatment_group (str) – Name of treatment group indicator column (0/1).

  • unit (str, optional) – Name of unit identifier column. If provided, computes unit-level changes. Otherwise uses observation-level data.

  • pre_periods (list, optional) – List of pre-treatment time periods. If None, uses first half of periods.

  • n_permutations (int, default=1000) – Number of permutations for computing p-value.

  • seed (int, optional) – Random seed for reproducibility.

  • wasserstein_threshold (float, default=0.2) – Threshold for normalized Wasserstein distance. Values below this threshold (combined with p > 0.05) suggest parallel trends are plausible.

Returns:

Dictionary containing: - wasserstein_distance: Wasserstein distance between group distributions - wasserstein_p_value: Permutation-based p-value - ks_statistic: Kolmogorov-Smirnov test statistic - ks_p_value: KS test p-value - mean_difference: Difference in mean changes - variance_ratio: Ratio of variances in changes - treated_changes: Array of outcome changes for treated - control_changes: Array of outcome changes for control - parallel_trends_plausible: Boolean assessment

Return type:

dict

Examples

>>> results = check_parallel_trends_robust(
...     data, outcome='sales', time='year',
...     treatment_group='treated', unit='firm_id'
... )
>>> print(f"Wasserstein distance: {results['wasserstein_distance']:.4f}")
>>> print(f"P-value: {results['wasserstein_p_value']:.4f}")

Notes

The Wasserstein distance (Earth Mover’s Distance) measures the minimum “cost” of transforming one distribution into another. Unlike simple mean comparisons, it captures differences in the entire distribution shape, making it more robust to non-normal data and heterogeneous effects.

A small Wasserstein distance and high p-value suggest the distributions of pre-treatment changes are similar, supporting the parallel trends assumption.

previous

diff_diff.check_parallel_trends

next

diff_diff.equivalence_test_trends

Show Source

© Copyright 2026, diff-diff contributors.

Created using Sphinx 9.0.4.

Built with the PyData Sphinx Theme 0.18.0.