CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-simple-statistics

A JavaScript implementation of descriptive, regression, and inference statistics

Pending
Overview
Eval results
Files

quantiles.mddocs/

Quantiles and Ranges

Functions for calculating percentiles, quartiles, and range statistics.

Core Imports

import { 
  quantile,
  quantileSorted,
  quantileRank,
  quantileRankSorted,
  interquartileRange,
  medianAbsoluteDeviation,
  min,
  max,
  extent,
  minSorted,
  maxSorted,
  extentSorted
} from "simple-statistics";

Quantile Functions

quantile { .api }

function quantile(values: number[], p: number): number;
function quantile(values: number[], p: number[]): number[];

Calculates quantiles (percentiles) from a dataset. Automatically sorts the data.

Parameters:

  • values: number[] - Array of numeric values
  • p: number | number[] - Quantile(s) to calculate (0-1 range)

Returns: number | number[] - Quantile value(s)

Common Quantiles:

  • 0.25 = 25th percentile (Q1)
  • 0.50 = 50th percentile (median, Q2)
  • 0.75 = 75th percentile (Q3)
import { quantile } from "simple-statistics";

const testScores = [65, 70, 75, 80, 85, 90, 95];

// Single quantile
const median = quantile(testScores, 0.5); // 80
const q1 = quantile(testScores, 0.25); // 70
const q3 = quantile(testScores, 0.75); // 90

// Multiple quantiles at once
const quartiles = quantile(testScores, [0.25, 0.5, 0.75]);
// [70, 80, 90]

console.log(`Q1: ${q1}, Median: ${median}, Q3: ${q3}`);

quantileSorted { .api }

function quantileSorted(values: number[], p: number): number;
function quantileSorted(values: number[], p: number[]): number[];

Optimized quantile calculation for pre-sorted arrays.

Parameters:

  • values: number[] - Pre-sorted array of numeric values
  • p: number | number[] - Quantile(s) to calculate (0-1 range)

Returns: number | number[] - Quantile value(s)

import { quantileSorted } from "simple-statistics";

// Data must be pre-sorted
const sortedScores = [65, 70, 75, 80, 85, 90, 95];
const percentiles = quantileSorted(sortedScores, [0.1, 0.5, 0.9]);
// [67, 80, 93] - 10th, 50th, 90th percentiles

Quantile Ranks

quantileRank { .api }

function quantileRank(values: number[], value: number): number;

Calculates what percentile a specific value represents in the dataset.

Parameters:

  • values: number[] - Array of numeric values
  • value: number - Value to find the rank for

Returns: number - Quantile rank (0-1 range)

import { quantileRank } from "simple-statistics";

const classScores = [60, 65, 70, 75, 80, 85, 90, 95];
const studentScore = 80;

const rank = quantileRank(classScores, studentScore); // 0.625
const percentile = Math.round(rank * 100); // 63rd percentile

console.log(`Score of ${studentScore} is at the ${percentile}th percentile`);

quantileRankSorted { .api }

function quantileRankSorted(values: number[], value: number): number;

Optimized quantile rank calculation for pre-sorted arrays.

Range Statistics

interquartileRange (alias: iqr) { .api }

function interquartileRange(values: number[]): number;

Calculates the interquartile range (Q3 - Q1), a robust measure of spread.

Parameters:

  • values: number[] - Array of numeric values

Returns: number - IQR value

Use Cases:

  • Robust measure of variability (less sensitive to outliers than standard deviation)
  • Box plot construction
  • Outlier detection (values beyond Q1-1.5×IQR or Q3+1.5×IQR)
import { interquartileRange, quantile } from "simple-statistics";

const salaries = [35000, 40000, 45000, 50000, 55000, 60000, 120000]; // One outlier

const iqr = interquartileRange(salaries); // 15000
const q1 = quantile(salaries, 0.25); // 42500
const q3 = quantile(salaries, 0.75); // 57500

console.log(`IQR: $${iqr.toLocaleString()}`);
console.log(`Middle 50% of salaries: $${q1.toLocaleString()} - $${q3.toLocaleString()}`);

// Outlier detection
const lowerFence = q1 - 1.5 * iqr; // 20000
const upperFence = q3 + 1.5 * iqr; // 80000

const outliers = salaries.filter(salary => salary < lowerFence || salary > upperFence);
console.log(`Outliers: $${outliers.map(s => s.toLocaleString()).join(', ')}`); // $120,000

medianAbsoluteDeviation (alias: mad) { .api }

function medianAbsoluteDeviation(values: number[]): number;

Calculates the median absolute deviation, another robust measure of variability.

Parameters:

  • values: number[] - Array of numeric values

Returns: number - MAD value

Formula: MAD = median(|xi - median(x)|)

import { medianAbsoluteDeviation, median } from "simple-statistics";

const responseTime = [120, 125, 130, 135, 200]; // One slow response

const medianTime = median(responseTime); // 130ms
const mad = medianAbsoluteDeviation(responseTime); // 5ms

console.log(`Median response: ${medianTime}ms`);
console.log(`MAD: ${mad}ms`);
// MAD is less affected by the 200ms outlier than standard deviation would be

Min/Max and Extent

min { .api }

function min(values: number[]): number;

Finds the minimum value in an array.

max { .api }

function max(values: number[]): number;

Finds the maximum value in an array.

extent { .api }

function extent(values: number[]): [number, number];

Returns both minimum and maximum as a tuple.

Parameters:

  • values: number[] - Array of numeric values

Returns: [number, number] - Tuple containing [minimum, maximum]

import { min, max, extent } from "simple-statistics";

const temperatures = [-5, 0, 12, 18, 25, 30];

const minTemp = min(temperatures); // -5
const maxTemp = max(temperatures); // 30
const tempRange = extent(temperatures); // [-5, 30]

console.log(`Temperature range: ${tempRange[0]}°C to ${tempRange[1]}°C`);
console.log(`Temperature span: ${tempRange[1] - tempRange[0]}°C`);

Sorted Array Optimizations

For pre-sorted arrays, use these optimized versions:

function minSorted(values: number[]): number;
function maxSorted(values: number[]): number;
function extentSorted(values: number[]): [number, number];

Optimized extent calculation for pre-sorted arrays.

Parameters:

  • values: number[] - Pre-sorted array of numeric values

Returns: [number, number] - Tuple containing [minimum, maximum]

import { minSorted, maxSorted, extentSorted } from "simple-statistics";

// Pre-sorted data
const sortedPrices = [9.99, 12.50, 15.75, 22.00, 35.99];

const cheapest = minSorted(sortedPrices); // 9.99
const mostExpensive = maxSorted(sortedPrices); // 35.99
const priceRange = extentSorted(sortedPrices); // [9.99, 35.99]

Usage Examples

Performance Analysis Dashboard

import { quantile, interquartileRange, quantileRank } from "simple-statistics";

// Website response times (ms)
const responseTimes = [
  45, 52, 48, 67, 55, 50, 47, 53, 49, 51, 46, 54, 48, 52, 50,
  49, 47, 53, 51, 48, 50, 65, 58, 44, 56, 49, 52, 47, 53, 150  // One slow outlier
];

// Calculate performance metrics
const percentiles = quantile(responseTimes, [0.5, 0.95, 0.99]);
const [median, p95, p99] = percentiles;

const iqr = interquartileRange(responseTimes);
const slaThreshold = 100; // 100ms SLA
const slaPercentile = quantileRank(responseTimes, slaThreshold);

console.log("Performance Dashboard:");
console.log(`Median response time: ${median}ms`);
console.log(`95th percentile: ${p95}ms`);
console.log(`99th percentile: ${p99}ms`);
console.log(`IQR: ${iqr}ms`);
console.log(`SLA compliance: ${(slaPercentile * 100).toFixed(1)}% under ${slaThreshold}ms`);

// Alerting based on percentiles
if (p95 > 80) {
  console.log("🚨 Alert: 95th percentile exceeds 80ms threshold");
}

Salary Band Analysis

import { quantile, quantileRank, interquartileRange } from "simple-statistics";

// Company salary data
const salaries = [
  45000, 48000, 52000, 55000, 58000, 62000, 65000, 68000, 72000, 75000,
  78000, 82000, 85000, 90000, 95000, 100000, 110000, 120000, 150000, 200000
];

// Define salary bands using quartiles
const salaryBands = quantile(salaries, [0.25, 0.5, 0.75]);
const [q1, median, q3] = salaryBands;

console.log("Salary Band Analysis:");
console.log(`Entry Level (0-25th): Up to $${q1.toLocaleString()}`);
console.log(`Mid Level (25-50th): $${q1.toLocaleString()} - $${median.toLocaleString()}`);
console.log(`Senior Level (50-75th): $${median.toLocaleString()} - $${q3.toLocaleString()}`);
console.log(`Executive (75th+): $${q3.toLocaleString()}+`);

// Individual salary analysis
const candidateSalary = 87000;
const candidatePercentile = quantileRank(salaries, candidateSalary);

console.log(`\nCandidate Analysis:`);
console.log(`Salary: $${candidateSalary.toLocaleString()}`);
console.log(`Percentile: ${Math.round(candidatePercentile * 100)}th`);

if (candidatePercentile > 0.75) {
  console.log("Band: Executive Level");
} else if (candidatePercentile > 0.5) {
  console.log("Band: Senior Level");
} else if (candidatePercentile > 0.25) {
  console.log("Band: Mid Level");
} else {
  console.log("Band: Entry Level");
}

Outlier Detection

import { quantile, interquartileRange, medianAbsoluteDeviation } from "simple-statistics";

// Stock price changes (%)
const priceChanges = [
  -2.1, -1.5, -0.8, 0.2, 0.5, 1.2, 1.8, 2.3, -1.2, 0.8,
  1.5, -0.5, 2.1, -1.8, 0.3, 1.1, -15.2, 2.5, -0.9, 1.7  // -15.2% is outlier
];

// IQR method for outlier detection
const [q1, q3] = quantile(priceChanges, [0.25, 0.75]);
const iqr = interquartileRange(priceChanges);
const lowerFence = q1 - 1.5 * iqr;
const upperFence = q3 + 1.5 * iqr;

const iqrOutliers = priceChanges.filter(change => 
  change < lowerFence || change > upperFence
);

// MAD method for outlier detection (more robust)
const mad = medianAbsoluteDeviation(priceChanges);
const median = quantile(priceChanges, 0.5);
const madThreshold = 3; // 3 MADs from median

const madOutliers = priceChanges.filter(change => 
  Math.abs(change - median) > madThreshold * mad
);

console.log("Outlier Detection Results:");
console.log(`IQR method: ${iqrOutliers.length} outliers: ${iqrOutliers.map(x => x.toFixed(1)).join(', ')}%`);
console.log(`MAD method: ${madOutliers.length} outliers: ${madOutliers.map(x => x.toFixed(1)).join(', ')}%`);
console.log(`Normal range (IQR): ${lowerFence.toFixed(1)}% to ${upperFence.toFixed(1)}%`);

Install with Tessl CLI

npx tessl i tessl/npm-simple-statistics

docs

array-operations.md

combinatorics.md

data-manipulation.md

descriptive-statistics.md

distributions.md

index.md

machine-learning.md

math-utilities.md

quantiles.md

regression.md

testing.md

tile.json