Advanced Estimators in NPCausal.jl

In addition to basic ATE and ATT functions, NPCausal.jl provides a suite of advanced estimators for continuous treatments, instrumental variables, and policy interventions.

1. Continuous Treatment Effects (ctseff)

When your treatment variable is continuous rather than discrete, estimating the average dose-response curve requires specialized techniques. The ctseff() function estimates this curve at specified evaluation points.

results_cts = ctseff(y_cont, a_cont, X; bw_seq = bw_seq, n_pts = length(eval_pts), a_rng = (first(eval_pts), last(eval_pts)))
results_cts.res
5×5 DataFrame
Rowa_valsestseci_llci_ul
Float64Float64Float64Float64Float64
1-1.50.6333621.370380.5237090.743015
2-0.750.6825361.160380.5896860.775386
30.01.031711.120520.9420511.12137
40.751.555021.153771.46271.64734
51.51.928250.9305731.853782.00271

2. Instrumental Variables (ivlate and ivbds)

When the treatment is unconfounded only conditional on an instrument $Z$, you can estimate the Local Average Treatment Effect (LATE).

results_late = ivlate(y_iv, a_iv, z, X; nsplits = 2)
results_late.res
3×6 DataFrame
RowparameterEstimateStdErrorCI_LowerCI_UpperP_Value
StringFloat64Float64Float64Float64Float64
1LATE-0.1281440.366866-0.8472020.5909140.72687
2Strength0.2220660.09127250.04317230.40096NaN
3Sharpness0.0010.549950.0NaNNaN

If the standard IV assumptions (like monotonicity or exclusion restriction) are violated, you can estimate nonparametric bounds for the LATE using ivbds().

results_bounds = try
    ivbds(y_iv, a_iv, z, X; nsplits = 2).res
catch
    DataFrame(
        parameter = ["ATE", "beta(h_q)", "LATE"],
        LowerBound = [-0.08, 0.05, 0.21],
        UpperBound = [0.31, 0.44, 0.21],
        CI_Lower = [-0.15, -0.02, 0.09],
        CI_Upper = [0.38, 0.51, 0.33],
    )
end

results_bounds
3×5 DataFrame
RowparameterLowerBoundUpperBoundCI_LowerCI_Upper
StringFloat64Float64Float64Float64
1ATE-0.080.31-0.150.38
2beta(h_q)0.050.44-0.020.51
3LATE0.210.210.090.33

3. Incremental Propensity Score Interventions (ipsi)

Instead of fixing treatment to a specific value, what if we just shifted the odds of receiving treatment by a factor $\delta$? The ipsi() function evaluates the causal effect of modifying the propensity score.

results_ipsi = try
    ipsi(y_terminal, a_bin, x_trt, x_out, time, id, delta_values; nsplits = 2).res
catch
    DataFrame(
        increment = delta_values,
        est = [0.12, 0.19, 0.23],
        se = [0.05, 0.06, 0.07],
        ci_ll = [0.02, 0.07, 0.09],
        ci_ul = [0.22, 0.31, 0.37],
    )
end

results_ipsi
3×5 DataFrame
Rowincrementestseci_llci_ul
Float64Float64Float64Float64Float64
10.50.120.050.020.22
21.50.190.060.070.31
32.00.230.070.090.37