diff_diff.RDDensityTest#
- class diff_diff.RDDensityTest[source]#
Bases:
BaseEstimatorManipulation testing via local polynomial density estimation (rddensity 3.0 parity).
Tests the null of NO discontinuity in the running variable’s density at the cutoff (McCrary 2008’s question) with the boundary-adaptive local polynomial density estimator of Cattaneo, Jansson & Ma (2020) and robust bias-corrected inference: density estimators of order
q = p + 1are evaluated at bandwidths selected as MSE-optimal for the order-pestimator. Defaults reproduce Rrddensity(X):p=2, triangular kernel, jackknife variance, unrestricted model,bwselect="comb", mass-point adjustment on.Assumptions (CJM 2020 Assumption 1, held separately on each side of the cutoff): the observations are an i.i.d. random sample, and the running variable’s distribution function is smooth with a POSITIVE density near the cutoff on each side. The jackknife/plugin variances assume cross-observation independence - clustered, survey-weighted, or repeated-observation dependence is NOT supported by the reviewed theory and there is no
cluster=surface here. Interpret non-rejection as “no density discontinuity detected”, which supports but never proves the RD continuity assumptions; a significant test is evidence of sorting around the cutoff.- Parameters:
cutoff (float, default 0.0) – The threshold
cin the support of the running variable.p (int, default 2) – Local polynomial order for the density point estimators (1..7, R’s accepted surface).
q (int or None, default None) – Order for the bias-corrected estimators;
Noneresolves top + 1at fit time (R uses aq=0sentinel). An explicitqmust satisfyq >= p;q == pgives the conventional (uncorrected) test, which OVER-REJECTS at data-driven MSE-optimal bandwidths (CJM 2020 Section 4) - valid conventional inference requires a manually undersmoothedh, the caller’s responsibility (a fit-time warning fires whenhis data-driven).fitselect (str, default "unrestricted") –
"unrestricted": separate model on each side."restricted": equal distribution function and higher-order derivatives across the cutoff (only the density may jump); requires equal bandwidths and forbidsbwselect="each".kernel (str, default "triangular") – “triangular”, “epanechnikov”, or “uniform” (R spellings “tri”/”epa”/”uni” accepted).
vcov_type (str, default "jackknife") – Variance estimator: “jackknife” (R’s default; the SA Section 5.2 leave-one-out construction, window-restricted as in R) or “plugin” (asymptotic plug-in).
h (float or (float, float) or None, default None) – Manual bandwidth(s). A scalar applies to both sides; a pair is
(h_left, h_right).Noneselects data-driven bandwidths.bwselect (str, default "comb") – Bandwidth selection: “each” (per-side MSE), “diff” (MSE of the difference), “sum” (MSE of the sum), “comb” (median of each/diff/sum per side for the unrestricted model; min of diff/sum for the restricted model). Ignored when
his supplied.masspoints (str, default "adjust") – Mass-point handling: “adjust” (R
massPoints=TRUE- the EDF is computed on unique values and replicated back, with a warning), “check” (detect repeated values and warn WITHOUT adjusting - estimation matches RmassPoints=FALSE), “off” (no detection). String surface matching the RD-familymasspointsdomain (documented Deviation from R’s boolean).regularize (bool, default True) – Local sample-size regularization of the data-driven bandwidths.
n_local_min (real or None, default None -> 20 + p + 1) – Minimum observations in each local neighborhood (final-stage floor).
ceil()is applied as in R;ceil(value) >= 0required, 0 disables the gate. Must be finite (Deviation from R, which accepts Inf).n_unique_min (real or None, default None -> 20 + p + 1) – Minimum unique observations in each local neighborhood; same contract as
n_local_min.report_all (bool, default False) – Also compute and report the conventional (order-
p) test alongside the robust one (R’sall=TRUE). The conventional test’s inference carries the same over-rejection caveat asq == pat data-driven bandwidths (seeqabove).
Examples
>>> test = RDDensityTest(cutoff=0.0) >>> result = test.fit(df, running="score") >>> result.t_stat, result.p_value # robust bias-corrected test
Methods
__init__([cutoff, p, q, fitselect, kernel, ...])fit(data, running)Run the manipulation test on
data[running].get_params([deep])Get estimator parameters (sklearn-compatible).
set_params(**params)Set estimator parameters (sklearn-compatible, transactional).
- __init__(cutoff=0.0, p=2, q=None, fitselect='unrestricted', kernel='triangular', vcov_type='jackknife', h=None, bwselect='comb', masspoints='adjust', regularize=True, n_local_min=None, n_unique_min=None, report_all=False)[source]#
- classmethod __new__(*args, **kwargs)#