Skip to content

paradoxie/stat-engine

Repository files navigation

@plotnerd/stat-engine

npm version npm downloads bundle size license TypeScript test status

Multi-algorithm quartile & statistics engine — the calculation core behind PlotNerd.com.

Calculate quartiles using five different algorithms in a single call. Compare results, get smart recommendations, and generate verification code for R, Python, Excel, and WolframAlpha.

Why Five Algorithms?

Different tools calculate quartiles differently. The same dataset can produce different Q1 and Q3 values depending on the method:

Algorithm Compatible With Method
Tukey's Hinges Statistics textbooks, manual calculation Inclusive median splitting (may interpolate)
R-7 / Python R quantile(type=7), NumPy, SciPy, Google Sheets Linear interpolation h=(n-1)p+1
Excel INC Excel QUARTILE.INC, LibreOffice, WPS Hyndman-Fan Type 7
Excel EXC Excel QUARTILE.EXC Hyndman-Fan Type 6 h=(n+1)p
WolframAlpha WolframAlpha, Mathematica, R type=5 R-5 interpolation h=np+0.5

🔗 See it in action: Interactive Algorithm Comparison on PlotNerd.com

Install

npm install @plotnerd/stat-engine

Also works with yarn, pnpm, and bun:

yarn add @plotnerd/stat-engine
pnpm add @plotnerd/stat-engine
bun add @plotnerd/stat-engine

Quick Start

import { MultiAlgorithmEngine } from '@plotnerd/stat-engine';

// Calculate with all 5 algorithms at once
const data = [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49];
const results = MultiAlgorithmEngine.calculateAllAlgorithms(data);

// Access any algorithm's results
console.log(results.r_python_default.q1);     // 25.5
console.log(results.r_python_default.q3);     // 42.5
console.log(results.r_python_default.iqr);    // 17

// Full five-number summary
console.log(results.tukey_hinges.fiveNumberSummary);
// [6, 25.5, 40, 42.5, 49]

⚠️ Note: calculateAllAlgorithms requires at least 4 data points. Other APIs (calculateQuartiles, generateVerification, recommendAlgorithm) accept any non-empty array. All methods reject NaN, Infinity, and non-number values.

Configurable Instance Mode

// Custom precision (6 decimals) and 3×IQR extreme outlier detection
const engine = new MultiAlgorithmEngine({ precision: 6, fenceMultiplier: 3 });
const results = engine.calculate([1, 2, 3, 4, 5, 6, 7, 8]);

Each algorithm result includes:

{
  minimum, maximum, count, sum, mean,   // Basic stats
  q1, median, q3, iqr,                  // Quartiles
  fiveNumberSummary,                     // [min, Q1, median, Q3, max]
  variance, standardDeviation,           // Dispersion
  outliers, outlierIndices,              // Outlier detection
  lowerFence, upperFence,               // 1.5×IQR fences
  dataRange, calculationTime             // Metadata
}

API

MultiAlgorithmEngine.calculateAllAlgorithms(data)

Calculate results using all five algorithms. Returns outliers, fences, IQR, mean, and five-number summary for each.

const results = MultiAlgorithmEngine.calculateAllAlgorithms([1, 2, 3, 4, 5, 6, 7, 8]);
// results.tukey_hinges, results.r_python_default, results.excel_inclusive, etc.

MultiAlgorithmEngine.calculateQuartiles(sortedData, algorithm)

Calculate quartiles using a specific algorithm.

const sorted = [1, 2, 3, 4, 5, 6, 7, 8];
const { q1, median, q3 } = MultiAlgorithmEngine.calculateQuartiles(sorted, 'r_python_default');

Available algorithms: tukey_hinges | r_python_default | excel_inclusive | excel_exclusive | wolfram_alpha

MultiAlgorithmEngine.compareAlgorithms(results, baseAlgorithm?)

Compare all algorithms against a baseline (default: r_python_default). Returns differences classified as identical, minor, significant, or major.

const results = MultiAlgorithmEngine.calculateAllAlgorithms(data);
const comparisons = MultiAlgorithmEngine.compareAlgorithms(results);
comparisons.forEach(c => console.log(`${c.algorithm}: ${c.significance}`));

MultiAlgorithmEngine.recommendAlgorithm(data, context?)

Get a smart recommendation based on data characteristics and user context.

const rec = MultiAlgorithmEngine.recommendAlgorithm(data, {
  userSoftware: 'Excel',   // → recommends excel_inclusive
  useCase: 'teaching',      // → recommends tukey_hinges
  experience: 'beginner'    // → recommends tukey_hinges
});
console.log(rec.recommended, rec.confidence); // 'excel_inclusive', 0.95

Error Handling

All errors extend StatEngineError so you can catch them with a single base class or drill into specifics:

import { ValidationError, AlgorithmError, StatEngineError } from '@plotnerd/stat-engine';

try {
    const results = engine.calculate(data);
} catch (err) {
    if (err instanceof ValidationError) {
        console.error(`Input error on field '${err.field}': ${err.message}`);
    } else if (err instanceof AlgorithmError) {
        console.error(`Algorithm '${err.algorithm}' failed: ${err.message}`);
    }
}

Error matrix by API

Method Throws When
calculateAllAlgorithms ValidationError (field: data) Array < 4 elements, non-finite values, non-number types
calculateQuartiles ValidationError (field: sortedData) Empty array, unsorted, non-finite values
compareAlgorithms ValidationError (field: results / baseAlgorithm) Null/incomplete results object
recommendAlgorithm ValidationError (field: data / userSoftware / useCase) Empty array, non-string context fields
generateVerification ValidationError (field: options / data) Null/non-object options, empty array, non-finite values
new MultiAlgorithmEngine() ValidationError (field: precision / fenceMultiplier) Invalid config values

MultiAlgorithmEngine.generateVerification(options)

Generate verification code and links for R, Python, Excel, or WolframAlpha.

const verify = MultiAlgorithmEngine.generateVerification({
  algorithm: 'wolfram_alpha',
  data: [1, 2, 3, 4, 5]
});
console.log(verify.verificationUrl);  // WolframAlpha link
console.log(verify.verificationCode); // Copy-paste code

MultiAlgorithmEngine.getAvailableAlgorithms()

Returns metadata for all five algorithms, including name, description, category, compatible software, and precision type.

MultiAlgorithmEngine.getAlgorithmMetadata(algorithm)

Returns metadata for a specific algorithm.

Utility Functions

import { calculateMedian, kahanSum, roundToPrecision } from '@plotnerd/stat-engine';

calculateMedian([1, 2, 3, 4, 5]);     // 3
kahanSum([0.1, 0.2, 0.3]);            // 0.6 (compensated)
roundToPrecision(3.14159, 2);          // 3.14

TypeScript Support

Full TypeScript support with exported types:

import type {
  QuartileAlgorithm,
  StatisticalResults,
  MultiAlgorithmResults,
  AlgorithmComparison,
  AlgorithmRecommendation,
  RecommendationContext,
  VerificationResult,
} from '@plotnerd/stat-engine';

import {
  ValidationError,
  AlgorithmError,
} from '@plotnerd/stat-engine';

Numerical Accuracy

  • Kahan summation for compensated floating-point addition
  • Numerically stable median using overflow-safe midpoint calculation
  • Symmetric rounding — "round half away from zero" for statistical consistency
  • 4-decimal precision with epsilon-aware rounding
  • 130+ test cases covering edge cases, negative numbers, duplicates, precision, performance, and error handling

Browser & Node.js Support

Works in both environments:

Environment Version
Node.js 16+
Chrome 80+
Firefox 80+
Safari 14+
Edge 80+

Used By

  • PlotNerd.com — Professional quartile calculator & box plot creator with 10+ language support

Algorithm Details

For a deep dive into how each algorithm works and when to use which, check out:

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

git clone https://github.com/paradoxie/stat-engine.git
cd stat-engine
npm install
npm test

License

MIT © PlotNerd Team

About

Multi-algorithm quartile calculator for JavaScript/TypeScript — Tukey's Hinges, R-7, Excel QUARTILE.INC/EXC, WolframAlpha. Five-number summary, IQR, outlier detection. Powers plotnerd.com

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors