PHPackages                             cjuol/statguard - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. cjuol/statguard

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

cjuol/statguard
===============

Suite de estadística avanzada para PHP: cálculos robustos (IQR, S\*, MAD) vs clásicos, detección de sesgos y exportación CSV/JSON.

v1.1.0(3mo ago)017MITPHPPHP &gt;=8.1CI passing

Since Feb 9Pushed 3mo agoCompare

[ Source](https://github.com/cjuol/StatGuard)[ Packagist](https://packagist.org/packages/cjuol/statguard)[ RSS](/packages/cjuol-statguard/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (4)Used By (0)

🛡️ StatGuard: Robust Statistics &amp; Data Integrity for PHP
============================================================

[](#️-statguard-robust-statistics--data-integrity-for-php)

\[English\] | [Español](docs/index.es.md)

[![Latest Stable Version](https://camo.githubusercontent.com/1978a095e16973955e2a9e57212c6ca69751b7b204fd1d797fb1a8db01cf3ec8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f636a756f6c2f7374617467756172643f636f6c6f723d627269676874677265656e266c6162656c3d737461626c65)](https://packagist.org/packages/cjuol/statguard)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHP Tests](https://github.com/cjuol/statguard/actions/workflows/php-tests.yml/badge.svg)](https://github.com/cjuol/statguard/actions)[![Performance](https://camo.githubusercontent.com/79d58a50266971af6096af1214405ec58ef3718fb5dcd148c0919b31c3a01877/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f75726c3d68747470733a2f2f676973742e67697468756275736572636f6e74656e742e636f6d2f636a756f6c2f34313466386266313566626539353033633333326135633061353761363939662f7261772f7374617467756172642d706572662e6a736f6e)](https://gist.github.com/cjuol/414f8bf15fbe9503c332a5c0a57a699f)[![R-Compatibility](https://camo.githubusercontent.com/f833e2a60f67da3847b4b730fd64f1248da9913e1ce7c97dd5b21998437db0e6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f522d636f6d7061746962696c6974792d626c75653f7374796c653d666c61742d737175617265)](https://cran.r-project.org/)[![PHP 8.x](https://camo.githubusercontent.com/4b6fa6db1fdd7dcb4009cf685d9a0a2587b38e2dfbb2f7170e3820a2cf49ff9b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e782d3737374242343f7374796c653d666c61742d737175617265)](https://www.php.net/)

StatGuard is a robust statistical analysis suite for PHP focused on scientific precision and data integrity. It compares classic statistics against robust statistics to detect bias, noise, and measurement anomalies in a fully automated way.

Why StatGuard
-------------

[](#why-statguard)

Outliers are inevitable in telemetry, finance, sports tracking, and lab measurements. A single extreme value can pull the arithmetic mean far from the central mass, which biases decisions that depend on it. StatGuard provides robust estimators (median, MAD, trimmed and winsorized means, Huber M-estimator) that stay stable under contamination so you can trust summaries even when the data is messy.

Highlights
----------

[](#highlights)

- **ClassicStats**: Full classic descriptive statistics implementation.
- **StatsComparator**: The analysis core that evaluates data fidelity and issues a verdict.
- **ExportableTrait**: First-class CSV and JSON exports for every stats class.
- **Traits + Interfaces**: Built-in data validation and extensible architecture.
- **Independent engines**: `QuantileEngine` and `CentralTendencyEngine` keep core math isolated and reusable.
- **R parity**: Quantiles and robust means are validated against R outputs.

Features
--------

[](#features)

- 9 R-compatible quantile types (Hyndman &amp; Fan 1-9).
- Robust means: Huber, winsorized, and trimmed.

Installation
------------

[](#installation)

Install via Composer:

```
composer require cjuol/statguard
```

Usage
-----

[](#usage)

### Robust Estimators (Quick Start)

[](#robust-estimators-quick-start)

```
use Cjuol\StatGuard\RobustStats;

$stats = new RobustStats();
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1000];

$huber = $stats->getHuberMean($data);
$winsorized = $stats->getWinsorizedMean($data, 0.1);
$iqr = $stats->getIqr($data, RobustStats::TYPE_R_DEFAULT);
```

Robust estimators stay stable even with extreme outliers:

MetricResultCommentArithmetic Mean95.9091Pulled up by the outlierHuber Mean6.0982Stays close to the central mass### Example: Huber Mean

[](#example-huber-mean)

```
use Cjuol\StatGuard\RobustStats;

$robust = new RobustStats();
$data = [10, 12, 11, 15, 10, 1000];

$huber = $robust->getHuberMean($data, 1.345, 50, 0.001);
```

### Example: Winsorized Mean (R-Compatible Quantile Type)

[](#example-winsorized-mean-r-compatible-quantile-type)

```
use Cjuol\StatGuard\RobustStats;

$robust = new RobustStats();
$data = [10, 12, 11, 15, 10, 1000];

// Type 7 matches R's default quantile() behavior.
$winsorized = $robust->getWinsorizedMean($data, 0.1, 7);
```

### Comparator (Bias Detection)

[](#comparator-bias-detection)

```
use Cjuol\StatGuard\StatsComparator;

$comparator = new StatsComparator();
$data = [10, 12, 11, 15, 10, 1000];

$analysis = $comparator->analyze($data);

echo $analysis['verdict'];
// ALERT: Data is highly influenced by outliers. Use robust metrics.
```

### Instant Export

[](#instant-export)

```
use Cjuol\StatGuard\RobustStats;

$robust = new RobustStats();

file_put_contents('report.csv', $robust->toCsv($data));
echo $robust->toJson($data);
```

### Summary Keys (Classic vs Robust)

[](#summary-keys-classic-vs-robust)

Classic summary keys:

```
[
	'mean',
	'median',
	'stdDev',
	'sampleVariance',
	'cv',
	'outliersZScore',
	'count'
]
```

Robust summary keys:

```
[
	'mean',
	'median',
	'robustDeviation',
	'robustVariance',
	'robustCv',
	'iqr',
	'mad',
	'outliers',
	'confidenceIntervals',
	'count'
]
```

Metrics Comparison
------------------

[](#metrics-comparison)

MetricClassicStatsRobustStatsOutlier ImpactCenterMeanMedianHigh in classicDispersionStandard DeviationMAD (Scaled)Extreme in classicVariabilityCV%Robust CV%Very high in classicExportable✅ Yes✅ Yes-R Quantile Types (1-9)
----------------------

[](#r-quantile-types-1-9)

StatGuard matches R v4.x quantile definitions. The table below summarizes the nine Hyndman &amp; Fan (1996) types supported by `quantile()`.

Type$p\_k$$a$$b$Notes1$k / n$00Inverse of empirical CDF (discontinuous).2$k / n$00Averaged at discontinuities.3$(k - 0.5) / n$-0.50Nearest order statistic.4$k / n$01Linear interpolation of CDF.5$(k - 0.5) / n$0.50.5Hazen (1914).6$k / (n + 1)$01Weibull (1939).7$(k - 1) / (n - 1)$11R default, mode of $F(x)$.8$(k - 1/3) / (n + 1/3)$1/31/3Median-unbiased.9$(k - 3/8) / (n + 1/4)$3/83/8Normal-unbiased.Implemented Methods
-------------------

[](#implemented-methods)

### ClassicStats

[](#classicstats)

- `getMean(array $data): float`
- `getMedian(array $data): float`
- `getDeviation(array $data): float`
- `getStandardDeviation(array $data): float`
- `getCoefficientOfVariation(array $data): float`
- `getSampleVariance(array $data): float`
- `getPopulationVariance(array $data): float`
- `getOutliers(array $data): array`
- `getSummary(array $data, bool $sort = true, int $decimals = 2): array`
- `toJson(array $data, int $options = JSON_PRETTY_PRINT): string`
- `toCsv(array $data, string $delimiter = ","): string`

### RobustStats

[](#robuststats)

- `getMean(array $data): float`
- `getMedian(array $data): float`
- `getDeviation(array $data): float`
- `getCoefficientOfVariation(array $data): float`
- `getRobustDeviation(array $data): float`
- `getRobustCv(array $data): float`
- `getRobustVariance(array $data): float`
- `getIqr(array $data): float`
- `getMad(array $data): float`
- `getOutliers(array $data): array`
- `getConfidenceIntervals(array $data): array`
- `getTrimmedMean(array $data, float $trimPercentage = 0.1): float`
- `getWinsorizedMean(array $data, float $trimPercentage = 0.1, int $type = 7): float`
- `getHuberMean(array $data, float $k = 1.345, int $maxIterations = 50, float $tolerance = 0.001): float`
- `getSummary(array $data, bool $sort = true, int $decimals = 2): array`
- `toJson(array $data, int $options = JSON_PRETTY_PRINT): string`
- `toCsv(array $data, string $delimiter = ","): string`

### StatsComparator

[](#statscomparator)

- `__construct(?RobustStats $robust = null, ?ClassicStats $classic = null)`
- `analyze(array $data, int $decimals = 2): array`

Mathematical Basis
------------------

[](#mathematical-basis)

### Scaled Robust Deviation

[](#scaled-robust-deviation)

To keep comparisons fair, MAD is scaled to be comparable to standard deviation under normal distributions:

$$\\sigma\_{robust} = MAD \\times 1.4826$$

### Robust Coefficient of Variation ($CV\_r$)

[](#robust-coefficient-of-variation-cv_r)

Calculated over the median to avoid a single extreme value inflating volatility:

$$CV\_r = \\left( \\frac{\\sigma\_{robust}}{|\\tilde{x}|} \\right) \\times 100$$

R Compatibility &amp; Accuracy
------------------------------

[](#r-compatibility--accuracy)

Every public statistic is tested against R v4.x outputs to ensure scientific accuracy. Quantile calculations use Type 7 by default (the same default as `quantile()` in R), and robust central tendency methods (trimmed mean, winsorized mean, Huber M-estimator) are verified via R comparison scripts in the repository.

Docker Profiles (Optional R Validation)
---------------------------------------

[](#docker-profiles-optional-r-validation)

StatGuard does not require R for normal usage. The default container is lightweight and focused on PHP development. For scientific auditing, you can enable the `r-validation` profile to run the R comparison script.

```
# Default dev container (no R runtime)
docker compose up -d

# Run tests in the default container
composer run test

# Run R validation in the heavy profile
composer run validate-r
```

Performance Benchmarks (StatGuard vs MathPHP vs R)
--------------------------------------------------

[](#performance-benchmarks-statguard-vs-mathphp-vs-r)

Up to 5x faster than MathPHP in median calculations.

20x faster than MathPHP in robust mean estimation.

Dataset: 100,000 random floats. Benchmarks executed in the Docker performance profile using `docker compose --profile performance run --rm benchmark report`. R timings use `system.time()` and only measure computation (file load excluded).

Use `json` only when you need the shield data output (it does not update the markdown tables).

### Scientific Parity (vs R)

[](#scientific-parity-vs-r)

Status shows ✅ when the absolute difference between StatGuard and R is below 0.0001.

Generate or refresh the table with `php tests/BenchmarkStatGuard.php report`.

MethodStatGuard msStatGuard valueMathPHP msMathPHP valueR msR valueStatusMedian------❌Quantile Type 1 (p=0.75)------❌Quantile Type 2 (p=0.75)------❌Quantile Type 3 (p=0.75)------❌Quantile Type 4 (p=0.75)------❌Quantile Type 5 (p=0.75)------❌Quantile Type 6 (p=0.75)------❌Quantile Type 7 (p=0.75)------❌Quantile Type 8 (p=0.75)------❌Quantile Type 9 (p=0.75)------❌Huber mean------❌Metric (100k)StatGuard msMathPHP msR msRatio (PHP/R)Median15.876.52.007.92Quantile Type 7 (p=0.75)16.216.02.008.09Huber mean34.8788.710.003.48Precision check (Huber): $\\Delta = 0.0056111266$ for $n = 100000$ (warning threshold $10^{-10}$). Smaller datasets showed higher deltas, which are reported by the benchmark warnings.

Consistent results with R core within 0.01% tolerance on the benchmark scale (0-1000).

Tests and Quality
-----------------

[](#tests-and-quality)

Validated with PHPUnit for full coverage of calculations and data validation.

```
./vendor/bin/phpunit tests
```

License
-------

[](#license)

This project is licensed under the MIT License. See LICENSE for details.

Built with ❤️ by cjuol.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance82

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~2 days

Total

2

Last Release

96d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d805fbdbef64624488203f5abe5022e4a14a5f165601d47dfd9b4eb56998d10?d=identicon)[cjuol](/maintainers/cjuol)

---

Top Contributors

[![cjuol](https://avatars.githubusercontent.com/u/40854906?v=4)](https://github.com/cjuol "cjuol (23 commits)")

---

Tags

phpstatisticsdata-integritycsv-exportdata-analysisrobust-statisticsoutlierscomparative-statsstatguard

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/cjuol-statguard/health.svg)

```
[![Health](https://phpackages.com/badges/cjuol-statguard/health.svg)](https://phpackages.com/packages/cjuol-statguard)
```

###  Alternatives

[rubix/tensor

A library and extension that provides objects for scientific computing in PHP.

2751.4M5](/packages/rubix-tensor)[imanghafoori/laravel-anypass

A minimal yet powerful package to help you in development.

21421.6k](/packages/imanghafoori-laravel-anypass)[jacobemerick/kmeans

k-means clustering implemented in PHP

126.4k](/packages/jacobemerick-kmeans)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
