Quantiles and Percentiles Examples
Examples of working with quantiles, percentiles, and quartiles in @addmaple/stats.
Percentiles
Basic Percentile Calculation
js
import { init, percentile } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 50th percentile (median)
const median = percentile(data, 0.5);
console.log(median); // 5.5
// 90th percentile
const p90 = percentile(data, 0.9);
console.log(p90); // 9.1
// 25th percentile (Q1)
const q1 = percentile(data, 0.25);
console.log(q1); // 3.25Exclusive vs Inclusive Method
js
import { init, percentile } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5];
// Inclusive method (default, R7)
const inclusive = percentile(data, 0.5, false);
console.log(inclusive); // 3
// Exclusive method (R6)
const exclusive = percentile(data, 0.5, true);
console.log(exclusive); // 3Real-World Example: Test Scores
js
import { init, percentile } from '@addmaple/stats';
await init();
const scores = [65, 72, 78, 82, 85, 88, 90, 92, 95, 98];
// What score is at the 75th percentile?
const p75 = percentile(scores, 0.75);
console.log(`75th percentile: ${p75}`); // ~92
// What score is at the 25th percentile?
const p25 = percentile(scores, 0.25);
console.log(`25th percentile: ${p25}`); // ~78Quartiles
Basic Quartile Calculation
js
import { init, quartiles } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const { q1, q2, q3 } = quartiles(data);
console.log(`Q1: ${q1}`); // 3.25
console.log(`Q2 (median): ${q2}`); // 5.5
console.log(`Q3: ${q3}`); // 7.75Interquartile Range (IQR)
js
import { init, quartiles, iqr } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Calculate IQR directly
const range = iqr(data);
console.log(`IQR: ${range}`); // 4.5
// Or calculate from quartiles
const { q1, q3 } = quartiles(data);
const manualIqr = q3 - q1;
console.log(`Manual IQR: ${manualIqr}`); // 4.5Outlier Detection Using IQR
js
import { init, quartiles, iqr } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 50]; // 50 is an outlier
const { q1, q3 } = quartiles(data);
const iqrValue = iqr(data);
const lowerBound = q1 - 1.5 * iqrValue;
const upperBound = q3 + 1.5 * iqrValue;
const outliers = data.filter(x => x < lowerBound || x > upperBound);
console.log('Outliers:', outliers); // [50]Multiple Quantiles
Calculate Multiple Quantiles at Once
js
import { init, quantiles } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Calculate deciles (10th, 20th, ..., 90th percentiles)
const deciles = [];
for (let i = 1; i < 10; i++) {
deciles.push(i / 10);
}
const decileValues = quantiles(data, deciles);
console.log('Deciles:', decileValues);
// Float64Array [1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1]Vectorized Percentiles Helper
js
import { init, percentiles } from '@addmaple/stats';
await init();
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Request several percentiles in one call (10th, 50th, 90th)
const ps = [0.1, 0.5, 0.9];
const values = percentiles(data, ps);
console.log(values); // Float64Array [1.9, 5.5, 9.1]Percentiles of Score
js
import { init, percentileOfScore } from '@addmaple/stats';
await init();
const data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
// What percentile is score 75?
const percentile = percentileOfScore(data, 75);
console.log(`75 is at the ${percentile * 100}th percentile`); // ~70th percentile
// Strict comparison (< instead of <=)
const strict = percentileOfScore(data, 75, true);
console.log(`Strict: ${strict * 100}th percentile`);Real-World Examples
Income Distribution Analysis
js
import { init, quartiles, iqr, percentile } from '@addmaple/stats';
await init();
const incomes = [
25000, 30000, 35000, 40000, 45000,
50000, 55000, 60000, 70000, 80000,
90000, 100000, 120000, 150000, 200000
];
const { q1, q2, q3 } = quartiles(incomes);
const iqrValue = iqr(incomes);
console.log(`Median income: $${q2.toLocaleString()}`);
console.log(`Q1: $${q1.toLocaleString()}`);
console.log(`Q3: $${q3.toLocaleString()}`);
console.log(`IQR: $${iqrValue.toLocaleString()}`);
// Top 10% income
const top10 = percentile(incomes, 0.9);
console.log(`Top 10%: $${top10.toLocaleString()}`);Test Score Analysis
js
import { init, percentile, quartiles } from '@addmaple/stats';
await init();
const scores = [45, 52, 58, 62, 65, 68, 72, 75, 78, 82, 85, 88, 92, 95, 98];
// Grade boundaries
const aMin = percentile(scores, 0.9); // Top 10%
const bMin = percentile(scores, 0.7); // Top 30%
const cMin = percentile(scores, 0.5); // Top 50%
console.log(`A grade: >= ${aMin}`);
console.log(`B grade: >= ${bMin}`);
console.log(`C grade: >= ${cMin}`);
// Quartiles for box plot
const { q1, q2, q3 } = quartiles(scores);
console.log(`Box plot: [${q1}, ${q2}, ${q3}]`);Performance Metrics
js
import { init, percentile, quartiles } from '@addmaple/stats';
await init();
const responseTimes = [10, 12, 15, 18, 20, 22, 25, 28, 30, 35, 40, 45, 50];
// P50, P95, P99 percentiles
const p50 = percentile(responseTimes, 0.5);
const p95 = percentile(responseTimes, 0.95);
const p99 = percentile(responseTimes, 0.99);
console.log(`P50: ${p50}ms`);
console.log(`P95: ${p95}ms`);
console.log(`P99: ${p99}ms`);
// Quartiles for distribution understanding
const { q1, q2, q3 } = quartiles(responseTimes);
console.log(`Distribution: Q1=${q1}, Median=${q2}, Q3=${q3}`);Weighted Quantiles
When observations have different importance or frequency weights, use weighted quantiles instead of regular quantiles. This is common in survey data, aggregated statistics, or any scenario where values represent different numbers of observations.
Basic Weighted Percentile
js
import { init, weightedPercentile } from '@addmaple/stats';
await init();
const values = [1, 2, 3, 4, 5];
const weights = [1, 1, 1, 1, 5]; // Value 5 has 5x more weight
// Weighted median - pulled toward 5 due to higher weight
const median = weightedPercentile(values, weights, 0.5);
console.log(`Weighted median: ${median}`); // ~4.3
// Compare with equal weights (behaves like regular percentile)
const equalWeights = [1, 1, 1, 1, 1];
const regularMedian = weightedPercentile(values, equalWeights, 0.5);
console.log(`Regular median: ${regularMedian}`); // 3Weighted Median
js
import { init, weightedMedian } from '@addmaple/stats';
await init();
// Survey data: respondent ages with sampling weights
const ages = [25, 35, 45, 55, 65];
const sampleWeights = [100, 150, 200, 120, 80];
const medianAge = weightedMedian(ages, sampleWeights);
console.log(`Weighted median age: ${medianAge}`);Multiple Weighted Quantiles
js
import { init, weightedQuantiles } from '@addmaple/stats';
await init();
const income = [20000, 40000, 60000, 80000, 100000];
const population = [1000, 800, 500, 300, 100]; // More people earn less
// Calculate weighted quartiles
const [q1, median, q3] = weightedQuantiles(income, population, [0.25, 0.5, 0.75]);
console.log(`Q1: $${q1.toLocaleString()}`);
console.log(`Median: $${median.toLocaleString()}`);
console.log(`Q3: $${q3.toLocaleString()}`);
// Results weighted toward lower incomes due to population distributionWeighted Income Distribution
js
import { init, weightedPercentile, weightedQuantiles } from '@addmaple/stats';
await init();
// Income brackets with population counts (aggregated census data)
const incomes = [15000, 25000, 35000, 50000, 75000, 100000, 150000, 250000];
const householdCounts = [2000, 5000, 8000, 6000, 4000, 2500, 1000, 500];
// Calculate weighted percentiles
const p10 = weightedPercentile(incomes, householdCounts, 0.1);
const p50 = weightedPercentile(incomes, householdCounts, 0.5);
const p90 = weightedPercentile(incomes, householdCounts, 0.9);
console.log(`10th percentile income: $${p10.toLocaleString()}`);
console.log(`Median income: $${p50.toLocaleString()}`);
console.log(`90th percentile income: $${p90.toLocaleString()}`);
// Get all deciles at once
const decilePoints = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9];
const deciles = weightedQuantiles(incomes, householdCounts, decilePoints);
console.log('Income deciles:', Array.from(deciles).map(d => `$${d.toLocaleString()}`));Survey Response Analysis
js
import { init, weightedMedian, weightedQuantiles } from '@addmaple/stats';
await init();
// Survey responses with frequency weights
// (Each response represents multiple respondents with same answer)
const satisfactionScores = [1, 2, 3, 4, 5]; // 1-5 scale
const responseFrequencies = [50, 80, 200, 150, 120]; // Number of people
const medianSatisfaction = weightedMedian(satisfactionScores, responseFrequencies);
console.log(`Median satisfaction: ${medianSatisfaction.toFixed(2)}`);
// Get quartiles for box plot
const [q1, q2, q3] = weightedQuantiles(
satisfactionScores,
responseFrequencies,
[0.25, 0.5, 0.75]
);
console.log(`Satisfaction quartiles: Q1=${q1.toFixed(2)}, Q2=${q2.toFixed(2)}, Q3=${q3.toFixed(2)}`);