Implementation of the CHITEST() statistical function (#1960)
* Implementation of the CHITEST() statistical function * A couple of additional edge case tests (rows = 1, columns = 1)
This commit is contained in:
parent
a34dd71cce
commit
67fec4e3fc
|
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
|
|||
|
||||
### Added
|
||||
|
||||
- Implemented the CHITEST() Statistical function.
|
||||
- Support for ActiveSheet and SelectedCells in the ODS Reader and Writer. [PR #1908](https://github.com/PHPOffice/PhpSpreadsheet/pull/1908)
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
|
|
@ -518,12 +518,12 @@ class Calculation
|
|||
],
|
||||
'CHITEST' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'functionCall' => [Statistical\Distributions\ChiSquared::class, 'test'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'CHISQ.TEST' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Functions::class, 'DUMMY'],
|
||||
'functionCall' => [Statistical\Distributions\ChiSquared::class, 'test'],
|
||||
'argumentCount' => '2',
|
||||
],
|
||||
'CHOOSE' => [
|
||||
|
|
|
|||
|
|
@ -82,4 +82,45 @@ class ChiSquared
|
|||
|
||||
return $newtonRaphson->execute($probability);
|
||||
}
|
||||
|
||||
public static function test($actual, $expected)
|
||||
{
|
||||
$rows = count($actual);
|
||||
$actual = Functions::flattenArray($actual);
|
||||
$expected = Functions::flattenArray($expected);
|
||||
$columns = count($actual) / $rows;
|
||||
|
||||
$countActuals = count($actual);
|
||||
$countExpected = count($expected);
|
||||
if ($countActuals !== $countExpected || $countActuals === 1) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
|
||||
$result = 0.0;
|
||||
for ($i = 0; $i < $countActuals; ++$i) {
|
||||
if ($expected[$i] == 0.0) {
|
||||
return Functions::DIV0();
|
||||
} elseif ($expected[$i] < 0.0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$result += (($actual[$i] - $expected[$i]) ** 2) / $expected[$i];
|
||||
}
|
||||
|
||||
$degrees = self::degrees($rows, $columns);
|
||||
|
||||
$result = self::distribution($result, $degrees);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected static function degrees(int $rows, int $columns): int
|
||||
{
|
||||
if ($rows === 1) {
|
||||
return $columns - 1;
|
||||
} elseif ($columns === 1) {
|
||||
return $rows - 1;
|
||||
}
|
||||
|
||||
return ($columns - 1) * ($rows - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ChiTestTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerCHITEST
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $actual
|
||||
* @param mixed $expected
|
||||
*/
|
||||
public function testCHITEST($expectedResult, $actual, $expected): void
|
||||
{
|
||||
$result = Statistical\Distributions\ChiSquared::test($actual, $expected);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerCHITEST()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/CHITEST.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
0.0152703571482,
|
||||
[[112, 76], [85, 95]],
|
||||
[[100, 85], [70, 90]],
|
||||
],
|
||||
[
|
||||
0.000308192027,
|
||||
[[58, 35], [11, 25], [10, 23]],
|
||||
[[45.35, 47.65], [17.56, 18.44], [16.09, 16.91]],
|
||||
],
|
||||
[
|
||||
0.015888560447,
|
||||
[[58], [11], [10]],
|
||||
[[45.35], [17.56], [16.09]],
|
||||
],
|
||||
[
|
||||
0.008682970191,
|
||||
[[58, 35]],
|
||||
[[45.35, 47.65]],
|
||||
],
|
||||
[
|
||||
'#NUM!',
|
||||
[[58, 11], [10, 35], [25]],
|
||||
[[45.35, 17.56], [16.09, 47.65], [18.44, 16.91]],
|
||||
],
|
||||
[
|
||||
'#DIV/0!',
|
||||
[[112, 76], [85, 95]],
|
||||
[[100, 0], [70, 90]],
|
||||
],
|
||||
[
|
||||
'#NUM!',
|
||||
[[112, 76], [85, 95]],
|
||||
[[100, 85], [-70, 90]],
|
||||
],
|
||||
];
|
||||
Loading…
Reference in New Issue