Skip to main content

regression_diagnostics/influence/
dffits.rs

1use ndarray::Array1;
2
3use crate::residuals::externally_studentized_residuals;
4use crate::OlsFit;
5
6/// DFFITS `ᵢ` for each observation.
7///
8/// `DFFITSᵢ = tᵢ · √(hᵢ / (1 − hᵢ))`
9///
10/// where `tᵢ` is the **externally** studentized residual and `hᵢ` the leverage.
11/// It measures, in standard-error units, how much observation `i`'s own fitted
12/// value changes when that observation is deleted from the fit — a leave-one-out
13/// influence measure.
14///
15/// A commonly cited flag is `|DFFITSᵢ| > 2·√(p/n)` (convention, not a hard rule).
16///
17/// DFFITS uses the external (leave-one-out) residual scale, whereas
18/// [`cooks_distance`](super::cooks_distance) uses the internal one; the two
19/// normally agree, but DFFITS reacts more sharply to a lone extreme outlier since
20/// that point is excluded from the scale it is judged against. Entries are `NaN`
21/// where the external studentized residual is undefined (`n − p − 1 < 1`).
22pub fn dffits(fit: &OlsFit) -> Array1<f64> {
23    let t = externally_studentized_residuals(fit);
24    let lev = fit.leverage();
25
26    Array1::from_shape_fn(fit.n_observations(), |i| {
27        let h = lev[i];
28        let one_minus_h = 1.0 - h;
29        if one_minus_h <= 0.0 {
30            return f64::NAN;
31        }
32        t[i] * (h / one_minus_h).sqrt()
33    })
34}