@absoluteui/helpers/stats
Mean, median, percentiles, deviation, histograms, correlation, and regression.
import { ... } from '@absoluteui/helpers/stats';How to use
Section titled “How to use”Descriptive statistics for dashboards and reports: averages, percentiles, spread, outliers, histograms, trends, and simple regression. Functions return undefined for empty input rather than NaN, and reject NaN/Infinity unless you pass nonFinite: 'ignore'. Percentiles match Excel PERCENTILE.INC by default, and variance is the sample statistic (VAR.S) unless population: true. The Charts guide shows how to plot the results.
How do I summarise a salary band?
Section titled “How do I summarise a salary band?”Median and quartiles describe a pay band better than the mean, which a few high earners pull up.
import { mean, median, percentile, quartiles } from '@absoluteui/helpers/stats';
const salaries = [42_000, 45_000, 47_500, 48_000, 51_000, 53_000, 55_500, 120_000];mean(salaries); // => 57750median(salaries); // => 49500quartiles(salaries); // => [46875, 49500, 53625]percentile(salaries, 90); // => ≈ 74850How do I flag unusual overtime?
Section titled “How do I flag unusual overtime?”outliers applies Tukey fences (k: 1.5 by default, 3 for “far out”) and returns the input indexes, so you can point back to the employees.
import { outliers } from '@absoluteui/helpers/stats';
const team = [ { name: 'Asha', hours: 4 }, { name: 'Ben', hours: 6 }, { name: 'Chen', hours: 5 }, { name: 'Dana', hours: 7 }, { name: 'Eli', hours: 31 }, { name: 'Fay', hours: 5 },];const result = outliers(team.map((e) => e.hours));result?.indexes.map((i) => team[i]?.name); // => ['Eli']result?.upperFence; // => 9.375How do I bucket values for a distribution chart?
Section titled “How do I bucket values for a distribution chart?”histogram returns bins with inclusive lower and exclusive upper edges; binWidth aligns edges to round numbers such as ten-year age bands.
import { histogram } from '@absoluteui/helpers/stats';
const ages = [23, 27, 29, 31, 34, 35, 38, 41, 44, 52];histogram(ages, { binWidth: 10 }).map((b) => `${b.x0}–${b.x1 - 1}: ${b.count}`); // => ['20–29: 3', '30–39: 4', '40–49: 2', '50–59: 1']How do I smooth a monthly trend and project it forward?
Section titled “How do I smooth a monthly trend and project it forward?”movingAverage smooths noise; linearRegression fits a straight line and predict extends it. Treat projections as indicative only.
import { linearRegression, movingAverage } from '@absoluteui/helpers/stats';
const headcount = [120, 124, 123, 129, 133, 136];movingAverage(headcount, 3); // => [122.33333333333333, 125.33333333333333, 128.33333333333334, 132.66666666666666]const fit = linearRegression([1, 2, 3, 4, 5, 6], headcount);fit === undefined ? undefined : Math.round(fit.predict(9)); // => 145What goes wrong?
Section titled “What goes wrong?”Empty input gives undefined, and non-finite values (often a failed parse upstream) throw unless you opt in to skipping them:
import { mean } from '@absoluteui/helpers/stats';
mean([]); // => undefinedmean([5, Number.NaN, 7]); // => throws HLP_STATS_NOT_FINITEmean([5, Number.NaN, 7], { nonFinite: 'ignore' }); // => 6API reference
Section titled “API reference”Functions
Section titled “Functions”correlation
Pearson correlation in [-1, 1]; undefined for fewer than 2 pairs or a constant series.
function correlation(xs: readonly number[], ys: readonly number[], options?: StatsOptions): number | undefined;Example:
correlation([1, 2, 3], [3, 2, 1]) // => -1covariance
Covariance of paired series (sample by default).
function covariance(xs: readonly number[], ys: readonly number[], options?: VarianceOptions): number | undefined;Example:
covariance([1, 2, 3], [2, 4, 6]) // => 2cumulativeSum
Running totals (compensated).
function cumulativeSum(values: readonly number[], options?: StatsOptions): number[];Example:
cumulativeSum([0.1, 0.2, 0.3]) // => [0.1, 0.30000000000000004, 0.6] // naive running addition ends at 0.6000000000000001extent
[min, max] in one pass (no spread, safe for huge arrays).
function extent(values: readonly number[], options?: StatsOptions): [number, number] | undefined;Example:
extent([3, 1, 4]) // => [1, 4]frequencies
Occurrence counts in first-seen order (a Map, so any value type is safe as a key).
function frequencies<T>(values: Iterable<T>): Map<T, number>;Example:
frequencies(['a', 'b', 'a']) // => new Map([['a', 2], ['b', 1]])geometricMean
Geometric mean of non-negative values (0 if any is 0); undefined if any is negative.
function geometricMean(values: readonly number[], options?: StatsOptions): number | undefined;Example:
geometricMean([1, 4, 16]) // => 4harmonicMean
Harmonic mean of non-negative values (0 if any is 0); undefined if any is negative.
function harmonicMean(values: readonly number[], options?: StatsOptions): number | undefined;Example:
harmonicMean([1, 4, 4]) // => 2histogram
Equal-width histogram.
function histogram(values: readonly number[], options?: HistogramOptions): HistogramBin[];Example:
histogram([1, 2, 2, 3, 9], { bins: 2 }) // => [{ x0: 1, x1: 5, count: 4 }, { x0: 5, x1: 9, count: 1 }]iqr
Interquartile range Q3 - Q1.
function iqr(values: readonly number[], options?: PercentileOptions): number | undefined;Example:
iqr([1, 2, 3, 4, 5]) // => 2kurtosis
Excess kurtosis: sample-adjusted (Excel KURT, n >= 4) by default, or population g2.
function kurtosis(values: readonly number[], options?: VarianceOptions): number | undefined;Example:
kurtosis([1, 2, 3, 4]) // => ≈ -1.2linearRegression
Ordinary least squares fit y = slope|x + intercept; undefined for < 2 pairs or constant x.
function linearRegression(xs: readonly number[], ys: readonly number[], options?: StatsOptions): LinearRegression | undefined;Example:
linearRegression([1, 2, 3], [2, 4, 6])?.predict(4) // => 8mean
Arithmetic mean.
function mean(values: readonly number[], options?: StatsOptions): number | undefined;Example:
mean([1, 2, 3, 4]) // => 2.5median
Median (mean of the two middle values for even counts).
function median(values: readonly number[], options?: StatsOptions): number | undefined;Example:
median([3, 1, 4, 2]) // => 2.5mode
All most-frequent values, ascending (several for multi-modal data).
function mode(values: readonly number[], options?: StatsOptions): number[] | undefined;Example:
mode([1, 2, 2, 3, 3]) // => [2, 3]movingAverage
Trailing simple moving average; result has length - window + 1 entries (empty when window > length).
function movingAverage(values: readonly number[], window: number, options?: StatsOptions): number[];Example:
movingAverage([1, 2, 3, 4], 2) // => [1.5, 2.5, 3.5]normalize
Min-max scaling to [0, 1]; a constant series maps to all zeros.
function normalize(values: readonly number[], options?: StatsOptions): number[] | undefined;Example:
normalize([10, 15, 20]) // => [0, 0.5, 1]outliers
Tukey fences [Q1 - k|IQR, Q3 + k|IQR] and the values outside them.
function outliers(values: readonly number[], options?: OutlierOptions): OutlierResult | undefined;Example:
outliers([1, 2, 3, 4, 100])?.outliers // => [100]percentile
Percentile for p in [0, 100].
function percentile(values: readonly number[], p: number, options?: PercentileOptions): number | undefined;Example:
percentile([1, 2, 3, 4, 5], 90) // => 4.6 // Excel PERCENTILE.INCquantile
Quantile for q in [0, 1] (same methods as percentile).
function quantile(values: readonly number[], q: number, options?: PercentileOptions): number | undefined;Example:
quantile([1, 2, 3, 4], 0.25) // => 1.75quantiles
The n - 1 cut points dividing the data into n equal-probability groups (n in 2..1000).
function quantiles(values: readonly number[], n: number, options?: PercentileOptions): number[] | undefined;Example:
quantiles([1, 2, 3, 4, 5], 4) // => [2, 3, 4]quartiles
[Q1, median, Q3] (linear method).
function quartiles(values: readonly number[], options?: PercentileOptions): [number, number, number] | undefined;Example:
quartiles([1, 2, 3, 4, 5]) // => [2, 3, 4]rangeOf
Range max - min (named rangeOf to avoid clashing with the array module’s range).
function rangeOf(values: readonly number[], options?: StatsOptions): number | undefined;Example:
rangeOf([3, 1, 4]) // => 3skewness
Skewness: sample-adjusted (Excel SKEW, n >= 3) by default, or population g1.
function skewness(values: readonly number[], options?: VarianceOptions): number | undefined;Example:
skewness([1, 2, 3]) // => 0standardize
Z-scores of every value (sample standard deviation unless population). undefined when constant.
function standardize(values: readonly number[], options?: VarianceOptions): number[] | undefined;Example:
standardize([1, 2, 3]) // => [-1, 0, 1]stdDev
Standard deviation (sample by default).
function stdDev(values: readonly number[], options?: VarianceOptions): number | undefined;Example:
stdDev([2, 4, 4, 4, 5, 5, 7, 9], { population: true }) // => 2variance
Variance (sample by default; population: true for n). Sample variance needs >= 2 values.
function variance(values: readonly number[], options?: VarianceOptions): number | undefined;Example:
variance([2, 4, 4, 4, 5, 5, 7, 9], { population: true }) // => 4weightedMean
Weighted mean; weights must be finite and non-negative. undefined when all weights are 0.
function weightedMean(values: readonly number[], weights: readonly number[], options?: StatsOptions): number | undefined;Example:
weightedMean([80, 90], [1, 3]) // => 87.5zScore
Standard score (value - mean) / stdDev; undefined when stdDev is 0.
function zScore(value: number, meanValue: number, stdDevValue: number): number | undefined;Example:
zScore(130, 100, 15) // => 2Constants
Section titled “Constants”MAX_HISTOGRAM_BINS
Largest bin count histogram produces.
const MAX_HISTOGRAM_BINS = 10000;Interfaces
Section titled “Interfaces”HistogramBin
interface HistogramBin { readonly x0: number; readonly x1: number; readonly count: number;}HistogramOptions
interface HistogramOptions extends StatsOptions { readonly bins?: number; readonly binWidth?: number; readonly domain?: readonly [number, number];}LinearRegression
interface LinearRegression { readonly slope: number; readonly intercept: number; readonly r2: number; predict(x: number): number;}OutlierOptions
interface OutlierOptions extends StatsOptions { readonly k?: number;}OutlierResult
interface OutlierResult { readonly lowerFence: number; readonly upperFence: number; readonly outliers: number[]; readonly indexes: number[];}PercentileOptions
interface PercentileOptions extends StatsOptions { readonly method?: PercentileMethod;}StatsOptions
interface StatsOptions { readonly nonFinite?: 'throw' | 'ignore';}VarianceOptions
interface VarianceOptions extends StatsOptions { readonly population?: boolean;}PercentileMethod
Percentile interpolation methods (NumPy names); linear equals Excel PERCENTILE.INC.
type PercentileMethod = 'linear' | 'nearest' | 'lower' | 'higher' | 'midpoint';