Skip to content

Implement exact Appendix F pre-treatment DR estimand; expand help documentation - #1

Open
gorgeousfish wants to merge 1 commit into
mainfrom
devin/1783345026-appendix-f-pretrend
Open

Implement exact Appendix F pre-treatment DR estimand; expand help documentation#1
gorgeousfish wants to merge 1 commit into
mainfrom
devin/1783345026-appendix-f-pretrend

Conversation

@gorgeousfish

@gorgeousfish gorgeousfish commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

The pretrend branch now implements the pre-treatment doubly robust estimand of Imai, Qin & Yanagi (2026, Appendix F) exactly, instead of reusing the post-treatment formula over pre-treatment (g,t) pairs.

  • New didhetero_comp_threshold_ord(g, t, delta, t_vals) in mata/didhetero_utils_domain.mata: returns t_ord + delta for post-treatment pairs but g_ord + delta for pre-treatment pairs (t < g - delta), anchoring the not-yet-treated comparison pool at t = g (R_{g,g} instead of R_{g,t}) so cohorts treated within the pre-trend window are excluded from both the GPS and OR samples.
  • didhetero_gps.mata, didhetero_or.mata, didhetero_intermediate.mata all call this helper, keeping the three nuisance modules consistent.
  • didhetero_pair_in_domain (pretrend branch): always drops the base period t = g-delta-1 (zero by construction); for pre-treatment pairs under notyettreated without a never-treated cohort, admits a pair only when gbar > g + delta so a comparison pool exists.
  • ado/catt_gt.sthlp: pretrend documents the Appendix F implementation; biters() documents the (B+1)*alpha convention (e.g. biters(999) with alp(0.05)); zeval() documents that grids much narrower than the sample support of z shrink the analytical uniform band.

Estimates for pre-treatment pairs change only in designs where an intermediate cohort is treated inside the pre-trend window; post-treatment estimates are unchanged. Needs verification on Stata (no Stata on this machine); the same change is vendored in gorgeousfish/sjdidhetero PR #1, whose replication scripts exercise it.


Requested by: dlgiuxqnkj (dlgiuxqnkj@outlook.com)
Devin session: https://app.devin.ai/sessions/3764940bd621427aaf490b3bccdca47c


Summary by cubic

Implements the exact Appendix F pre-treatment doubly robust estimand by anchoring the not‑yet‑treated comparison at t = g for pre‑treatment (g,t) pairs. Only pre‑treatment estimates change when a cohort is treated inside the pre‑trend window; post‑treatment estimates are unchanged.

  • New Features
    • New helper didhetero_comp_threshold_ord: uses t+delta for post‑treatment pairs, g+delta for pre‑treatment pairs.
    • GPS, OR, and intermediate modules now call this helper for consistent comparison pools.
    • didhetero_pair_in_domain: always drops the base period t = g−delta−1; for pre‑treatment pairs with notyettreated and no never‑treated group, admits only when gbar > g+delta.
    • Help updates: pretrend now documents the Appendix F estimator; biters() notes the (B+1)*alpha convention (e.g., biters(999) with alp(0.05)); zeval() notes that narrow grids shrink analytical uniform bands.

Written for commit 781246f. Summary will update on new commits.

Review in cubic

…biters/pretrend conventions in help

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@cursor

cursor Bot commented Jul 6, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="mata/didhetero_utils_domain.mata">

<violation number="1" location="mata/didhetero_utils_domain.mata:157">
P1: With `pretrend control_group(notyettreated)` and no never-treated cohort, late post-treatment pairs can still be admitted even when no not-yet-treated controls exist. The fallback `return(1)` bypasses the same `gbar` support check used by the normal post-treatment domain, so these pairs can fail later in GPS/OR estimation instead of being excluded.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

if (gbar_ord >= .) return(0)
return(gbar_ord > g_ord + anticipation)
}
return(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: With pretrend control_group(notyettreated) and no never-treated cohort, late post-treatment pairs can still be admitted even when no not-yet-treated controls exist. The fallback return(1) bypasses the same gbar support check used by the normal post-treatment domain, so these pairs can fail later in GPS/OR estimation instead of being excluded.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mata/didhetero_utils_domain.mata, line 157:

<comment>With `pretrend control_group(notyettreated)` and no never-treated cohort, late post-treatment pairs can still be admitted even when no not-yet-treated controls exist. The fallback `return(1)` bypasses the same `gbar` support check used by the normal post-treatment domain, so these pairs can fail later in GPS/OR estimation instead of being excluded.</comment>

<file context>
@@ -121,7 +147,14 @@ real scalar didhetero_pair_in_domain(
+            if (gbar_ord >= .) return(0)
+            return(gbar_ord > g_ord + anticipation)
+        }
+        return(1)
     }
 
</file context>
Suggested change
return(1)
if (control_group == "nevertreated") {
return(has_never)
}
if (control_group == "notyettreated") {
if (has_never) return(1)
gbar_ord = didhetero_period_ord(gbar, t_vals)
if (gbar_ord >= .) return(0)
return(t_ord < gbar_ord - anticipation)
}
_error(198, "Invalid control_group: " + control_group)
return(0)

gorgeousfish added a commit that referenced this pull request Jul 6, 2026
… domain P1 bug

Integrate the pre-treatment doubly-robust estimand of Imai, Qin & Yanagi
Appendix F onto current main (manual/cherry-pick to preserve the UI-refactor
work; the PR branch was based on an older main).

Changes:
- didhetero_utils_domain.mata: add didhetero_comp_threshold_ord() — pre-treatment
  pairs (t < g-delta) anchor the not-yet-treated comparison pool at t = g
  (R_{g,g}, Eq. 2.31), while post-treatment pairs keep R_{g,t} (Eq. 2.6).
  Base period t = g-delta-1 excluded (Eq. 2.32-2.33).
- gps/or/intermediate.mata: route the comparison-pool threshold through the new
  helper so all three modules share the anchored pre-treatment logic.
- catt_gt.sthlp: document the pretrend Appendix F estimand, biters()'s
  (B+1)*alpha convention, and the zeval() analytic-CV note.

P1 fix (didhetero_pair_in_domain, pretrend branch):
  Post-treatment pairs no longer unconditionally return(1); they now enforce the
  same not-yet-treated support check as the main branch (t_ord < gbar_ord -
  anticipation) when there is no never-treated pool, per Assumption 2.5' which
  imposes s < gbar on pre- and post-treatment regimes alike.

Verification:
- New tests/test_pretrend_domain_p1.do: 19/19 pure-Mata domain unit checks
  (covers the P1 case has_never=0, pretrend, post-treatment, gbar<=g+delta ->
  rejected).
- Non-pretrend estimates byte-identical to pre-integration main across 5
  scenarios incl. bootstrap CIs (MD5 match).
- End-to-end pretrend pipeline expands the domain with the R_{g,g} pre-treatment
  pair and estimates successfully.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants