Skip to content

MedianCI

Description

MedianCI returns a confidence interval (CI) for the median using the inverse binomial distribution method. The calculated CI assumes no distribution – it is nonparametric – only that the observations in the sample are independent and that the sample is representative. The CI is conservative: the desired coverage is guaranteed and may actually be greater than desired.

The function returns three values: the lower and upper limits of the CI, and the actual coverage probability. The two values for the CI are in the input sample.

Background

This function uses the inverse binomial distribution to obtain a non-parametric confidence interval. Suppose you have a sample of size N=260N = 260. The corresponding binomial mass (non-cumulative) distribution function is shown below, along with the tails (in red) that come closest to having an area of 2.5% on each side.

Binomial distribution for N = 260 centred on 130 successes, with the tails below 114 and above 146 shaded red

Another way to think of this distribution is to apply it to the sorted values of the sample (with N=260N = 260). From lowest to highest you can use the binomial distribution to calculate the probability that each value is the median. The values for which that probability is above the significance level determine the values in the sample that could plausibly be the true median. The boundaries of that range are used to determine the confidence interval.

Syntax

MedianCI(data, [alpha=0.05]) where data is the input sample (any shape) and alpha is the desired significance level. By default the CI is returned with confidence of at least 95%.

Example

Usage is straightforward and illustrated below. Note that both boundaries of the CI are values in the input data. The Excel file with these formulas is attached.

MedianCI output: median -0.511, CI -0.567 to -0.446, coverage 0.9568; COUNTIF shows both limits are data values

Download: MedianCI.xlsx

Source Code

MedianCI = LAMBDA(
    X, // input data set (any shape)
    [alpha], // optional significance level, default 0.05
    LET(
        alpha, IF(ISOMITTED(alpha), 5%, alpha),
        n, COUNT(X),
        // need the sorted values for the CI
        Xs, SORT(TOCOL(X)),
        // calculate the indices of the sorted values
        index_lower, n - BINOM.INV(n, 0.5, 1 - alpha / 2) + 1,
        index_upper, BINOM.INV(n, 0.5, 1 - alpha / 2) + 1,
        CL, BINOM.DIST(index_upper - 1, n, 0.5, TRUE) - BINOM.DIST(index_lower - 1, n, 0.5, TRUE),
        // wider interval slightly if necessary (just once)
        index_LL, IF(CL < 1 - alpha, index_lower - 1, index_lower),
        // calculate the coverage probability
        Coverage, BINOM.DIST(index_upper - 1, n, 0.5, TRUE) -
            BINOM.DIST(index_LL - 1, n, 0.5, TRUE),
        // output the results
        VSTACK(INDEX(Xs, index_LL), INDEX(Xs, index_upper), Coverage)
    )
);