Skip to content

Qn

Description

This function calculates the Rousseeuw-Croux robust scale statistic. It is essentially the first quartile of pairwise distances between all values in the sample. It is far more efficient than IQR and MAD estimators for near-normal data and has as high a breakdown point as the MAD, but has a greater computational cost.

Syntax

Qn(data, [corrected=FALSE], [finite=TRUE]) where

  • data is the univariate data (any shape), filtering out non-numeric values
  • corrected is a boolean (default FALSE) that determines whether to divide by a correcting factor to estimate the std dev of normally-distributed data
  • finite is a boolean (default TRUE) on whether to apply a finite-sample correction factor.

Example

Usage is straightforward: pass in the data as the first argument, and if the corrected value is desired pass in a value of TRUE for the second argument. Note that Excel interprets any nonzero number as TRUE and it is common to use syntax like =Qn(data,1) to obtain the corrected Qn value for the data.

Source Code

Note that this is an O(n2)O(n^2) operation and will slow noticeably for large (n>1000n > 1000) sample sizes. Bootstrapping of such large samples will not be feasible on most machines, and you should switch to MAD or IQR in such situations.

Qn = LAMBDA(
    X, // input data (any shape)
    [corrected], // estimate std dev of normal data? Default is FALSE (raw statistic).
    [finite], // if corrected, apply finite-sample correction? Default TRUE
    LET(
        corrected, IF(ISOMITTED(corrected), FALSE, corrected),
        finite, IF(ISOMITTED(finite), TRUE, finite),
        Xc, TOCOL(X),
        Xn, FILTER(Xc, ISNUMBER(Xc)),
        n, ROWS(Xn),
        h, INT(n / 2) + 1,
        k, h * (h - 1) / 2,
        // full n x n matrix has n zeros on the diagonal and every pair twice,
        // so the k-th smallest pairwise distance is the (n + 2k)-th smallest entry
        D, ABS(Xn - TRANSPOSE(Xn)),
        q, SMALL(D, n + 2 * k),
        cnst, 1 / (SQRT(2) * NORM.S.INV(5 / 8)),
        dn, IF(NOT(finite), 1,
            IF(n <= 9,
                CHOOSE(MAX(n, 2) - 1, 0.399, 0.994, 0.512, 0.844, 0.611, 0.857, 0.669, 0.872),
                IF(ISODD(n), n / (n + 1.4), n / (n + 3.8))
            )
        ),
        IF(corrected, cnst * dn * q, q)
    )
);