Skip to content

Commit 55a710b

Browse files
authored
Merge pull request #261 from igerber/survey-tutorial-updates
Fix survey tutorial warnings, narrative, and chart rendering
2 parents e7c99ee + 0ea4ff2 commit 55a710b

3 files changed

Lines changed: 133 additions & 150 deletions

File tree

diff_diff/prep_dgp.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ def generate_survey_did_data(
11421142
fpc_per_stratum: float = 200.0,
11431143
weight_variation: str = "moderate",
11441144
psu_re_sd: float = 2.0,
1145+
psu_period_factor: float = 0.5,
11451146
unit_fe_sd: float = 1.0,
11461147
noise_sd: float = 0.5,
11471148
include_replicate_weights: bool = False,
@@ -1194,6 +1195,10 @@ def generate_survey_did_data(
11941195
psu_re_sd : float, default=2.0
11951196
Standard deviation of PSU random effects. Controls intra-cluster
11961197
correlation and drives DEFF > 1.
1198+
psu_period_factor : float, default=0.5
1199+
Multiplier for PSU-period interaction shocks (relative to psu_re_sd).
1200+
Higher values increase time-varying within-cluster correlation,
1201+
which survives DiD's time-differencing and inflates design-based SEs.
11971202
unit_fe_sd : float, default=1.0
11981203
Standard deviation of unit fixed effects.
11991204
noise_sd : float, default=0.5
@@ -1267,6 +1272,12 @@ def generate_survey_did_data(
12671272
f"(g >= 2 ensures at least one pre-treatment period)"
12681273
)
12691274

1275+
if not np.isfinite(psu_period_factor) or psu_period_factor < 0:
1276+
raise ValueError(
1277+
f"psu_period_factor must be finite and non-negative, "
1278+
f"got {psu_period_factor}"
1279+
)
1280+
12701281
valid_wv = ("none", "moderate", "high")
12711282
if weight_variation not in valid_wv:
12721283
raise ValueError(
@@ -1327,7 +1338,11 @@ def generate_survey_did_data(
13271338
# differencing in DiD. Without these, the time-invariant PSU RE
13281339
# cancels in the treatment-vs-control time-difference and the
13291340
# cluster-robust / survey SE would be *smaller* than naive OLS SE.
1330-
psu_period_re = rng.normal(0, psu_re_sd * 0.5, size=(n_psu_total, n_periods))
1341+
# Controlled by psu_period_factor (default 0.5); higher values
1342+
# increase time-varying clustering and inflate design-based SEs.
1343+
psu_period_re = rng.normal(
1344+
0, psu_re_sd * psu_period_factor, size=(n_psu_total, n_periods)
1345+
)
13311346

13321347
# --- Generate panel or repeated cross-sections ---
13331348
records = []

0 commit comments

Comments
 (0)