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 . 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.

Another way to think of this distribution is to apply it to the sorted values of the sample (with ). 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.

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)
)
);