Skip to content

Commit 6d266de

Browse files
committed
Adding sem() method
1 parent 010f7da commit 6d266de

6 files changed

Lines changed: 84 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- Adding `coefficientOfVariation()` method for relative dispersion (CV%), supporting both sample and population modes
77
- Adding `trimmedMean()` method for robust central tendency — computes the mean after removing outliers from each side
88
- Adding `weightedMedian()` method for computing the median with weighted observations
9+
- Adding `sem()` method for standard error of the mean
910

1011
## 1.2.5 - 2026-02-22
1112
- Adding `kurtosis()` method for excess kurtosis

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ The various mathematical statistics are listed below:
7878
| `percentile()` | value at any percentile (0–100) with linear interpolation |
7979
| `pstdev()` | Population standard deviation |
8080
| `stdev()` | Sample standard deviation |
81+
| `sem()` | Standard error of the mean (SEM) — measures precision of the sample mean |
8182
| `pvariance()` | variance for a population (supports pre-computed mean via `mu`) |
8283
| `variance()` | variance for a sample (supports pre-computed mean via `xbar`) |
8384
| `skewness()` | adjusted Fisher-Pearson sample skewness |
@@ -341,6 +342,22 @@ $stdev = Stat::stdev([1.5, 2.5, 2.5, 2.75, 3.25, 4.75], 4);
341342
// 1.0811
342343
```
343344

345+
#### Stat::sem( array $data, ?int $round = null )
346+
Return the standard error of the mean (SEM). SEM measures how precisely the sample mean estimates the population mean. It decreases as the sample size grows.
347+
348+
Formula: `stdev / sqrt(n)`
349+
350+
Requires at least 2 data points.
351+
352+
```php
353+
use HiFolks\Statistics\Stat;
354+
$sem = Stat::sem([2, 4, 4, 4, 5, 5, 7, 9]);
355+
// 0.7559...
356+
357+
$sem = Stat::sem([2, 4, 4, 4, 5, 5, 7, 9], 4);
358+
// 0.7559
359+
```
360+
344361
#### Stat::variance ( array $data, ?int $round = null, int|float|null $xbar = null)
345362
Variance is a measure of dispersion of data points from the mean.
346363
Low variance indicates that data points are generally similar and do not vary widely from the mean.

src/Stat.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,23 @@ public static function stdev(array $data, ?int $round = null): float
642642
return Math::round(sqrt($variance), $round);
643643
}
644644

645+
/**
646+
* Return the standard error of the mean (SEM).
647+
* SEM measures how precisely the sample mean estimates the population mean.
648+
*
649+
* Formula: stdev / sqrt(n)
650+
*
651+
* @param array<int|float> $data
652+
* @param int|null $round whether to round the result
653+
* @return float the standard error of the mean
654+
*
655+
* @throws InvalidDataInputException if data size is less than 2
656+
*/
657+
public static function sem(array $data, ?int $round = null): float
658+
{
659+
return Math::round(self::stdev($data) / sqrt(self::count($data)), $round);
660+
}
661+
645662
/**
646663
* Return the variance from the numeric data.
647664
*

src/Statistics.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,18 @@ public function stdev(?int $round = null): float
261261
return Stat::stdev($this->numericalArray(), $round);
262262
}
263263

264+
/**
265+
* Return the standard error of the mean (SEM).
266+
*
267+
* @param int|null $round whether to round the result
268+
*
269+
* @see Stat::sem()
270+
*/
271+
public function sem(?int $round = null): float
272+
{
273+
return Stat::sem($this->numericalArray(), $round);
274+
}
275+
264276
/**
265277
* Return the variance from the numeric data
266278
*

tests/StatTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,4 +1237,33 @@ public function test_weighted_median_zero_weight_throws(): void
12371237
$this->expectException(InvalidDataInputException::class);
12381238
Stat::weightedMedian([1, 2, 3], [1, 0, 1]);
12391239
}
1240+
1241+
// --- sem ---
1242+
1243+
public function test_sem(): void
1244+
{
1245+
$data = [2, 4, 4, 4, 5, 5, 7, 9];
1246+
$expected = Stat::stdev($data) / sqrt(Stat::count($data));
1247+
$this->assertEqualsWithDelta($expected, Stat::sem($data), 1e-10);
1248+
}
1249+
1250+
public function test_sem_with_rounding(): void
1251+
{
1252+
$data = [2, 4, 4, 4, 5, 5, 7, 9];
1253+
$result = Stat::sem($data, 4);
1254+
$this->assertEquals(round($result, 4), $result);
1255+
}
1256+
1257+
public function test_sem_decreases_with_larger_sample(): void
1258+
{
1259+
$small = [1, 2, 3, 4, 5];
1260+
$large = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
1261+
$this->assertGreaterThan(Stat::sem($large), Stat::sem($small));
1262+
}
1263+
1264+
public function test_sem_too_few_data_throws(): void
1265+
{
1266+
$this->expectException(InvalidDataInputException::class);
1267+
Stat::sem([5]);
1268+
}
12401269
}

tests/StatisticTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace HiFolks\Statistics\Tests;
44

55
use HiFolks\Statistics\Exception\InvalidDataInputException;
6+
use HiFolks\Statistics\Stat;
67
use HiFolks\Statistics\Statistics;
78
use PHPUnit\Framework\TestCase;
89

@@ -296,4 +297,11 @@ public function test_weighted_median(): void
296297
// Heavy weight on 3 → weighted median is 3
297298
$this->assertEqualsWithDelta(3.0, $s->weightedMedian([1, 1, 10]), 1e-10);
298299
}
300+
301+
public function test_sem(): void
302+
{
303+
$s = Statistics::make([2, 4, 4, 4, 5, 5, 7, 9]);
304+
$expected = Stat::stdev([2, 4, 4, 4, 5, 5, 7, 9]) / sqrt(8);
305+
$this->assertEqualsWithDelta($expected, $s->sem(), 1e-10);
306+
}
299307
}

0 commit comments

Comments
 (0)