Start splitting some of the basic Statistical functions out into separate classes (#1888)
* Start splitting some of the basic Statistical functions out into separate classes containing just a few similar functions * Splitting some of the basic Statistical functions out into separate classes containing just a few similar functions - MAX(), MAXA(), MIN() and MINA() * Splitting some more of the basic Statistical functions out into separate classes containing just a few similar functions - StandardDeviations and Variances
This commit is contained in:
parent
8721f795fc
commit
2eaf9b53aa
|
|
@ -328,17 +328,17 @@ class Calculation
|
|||
],
|
||||
'AVEDEV' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'AVEDEV'],
|
||||
'functionCall' => [Statistical\Averages::class, 'AVEDEV'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'AVERAGE' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'AVERAGE'],
|
||||
'functionCall' => [Statistical\Averages::class, 'AVERAGE'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'AVERAGEA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'AVERAGEA'],
|
||||
'functionCall' => [Statistical\Averages::class, 'AVERAGEA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'AVERAGEIF' => [
|
||||
|
|
@ -624,17 +624,17 @@ class Calculation
|
|||
],
|
||||
'COUNT' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'COUNT'],
|
||||
'functionCall' => [Statistical\Counts::class, 'COUNT'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'COUNTA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'COUNTA'],
|
||||
'functionCall' => [Statistical\Counts::class, 'COUNTA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'COUNTBLANK' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'COUNTBLANK'],
|
||||
'functionCall' => [Statistical\Counts::class, 'COUNTBLANK'],
|
||||
'argumentCount' => '1',
|
||||
],
|
||||
'COUNTIF' => [
|
||||
|
|
@ -1620,12 +1620,12 @@ class Calculation
|
|||
],
|
||||
'MAX' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'MAX'],
|
||||
'functionCall' => [Statistical\Maximum::class, 'MAX'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'MAXA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'MAXA'],
|
||||
'functionCall' => [Statistical\Maximum::class, 'MAXA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'MAXIFS' => [
|
||||
|
|
@ -1665,12 +1665,12 @@ class Calculation
|
|||
],
|
||||
'MIN' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'MIN'],
|
||||
'functionCall' => [Statistical\Minimum::class, 'MIN'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'MINA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'MINA'],
|
||||
'functionCall' => [Statistical\Minimum::class, 'MINA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'MINIFS' => [
|
||||
|
|
@ -2263,22 +2263,22 @@ class Calculation
|
|||
],
|
||||
'STDEV' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEV'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STDEV.S' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEV'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STDEV.P' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEVP'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STDEVA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'STDEVA'],
|
||||
'functionCall' => [Statistical\StandardDeviations::class, 'STDEVA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'STDEVP' => [
|
||||
|
|
@ -2524,32 +2524,32 @@ class Calculation
|
|||
],
|
||||
'VAR' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VAR'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VAR.P' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARP'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VARP'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VAR.S' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARFunc'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VAR'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VARA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARA'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VARA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VARP' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARP'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VARP'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VARPA' => [
|
||||
'category' => Category::CATEGORY_STATISTICAL,
|
||||
'functionCall' => [Statistical::class, 'VARPA'],
|
||||
'functionCall' => [Statistical\Variances::class, 'VARPA'],
|
||||
'argumentCount' => '1+',
|
||||
],
|
||||
'VDB' => [
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||
|
||||
class DAverage extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -38,7 +38,7 @@ class DAverage extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::AVERAGE(
|
||||
return Averages::AVERAGE(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||
|
||||
class DCount extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -36,7 +36,7 @@ class DCount extends DatabaseAbstract
|
|||
{
|
||||
$field = self::fieldExtract($database, $field);
|
||||
|
||||
return Statistical::COUNT(
|
||||
return Counts::COUNT(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||
|
||||
class DCountA extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@ class DCountA extends DatabaseAbstract
|
|||
{
|
||||
$field = self::fieldExtract($database, $field);
|
||||
|
||||
return Statistical::COUNTA(
|
||||
return Counts::COUNTA(
|
||||
self::getFilteredColumn($database, $field ?? 0, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
|
||||
|
||||
class DMax extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DMax extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::MAX(
|
||||
return Maximum::MAX(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
|
||||
|
||||
class DMin extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DMin extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::MIN(
|
||||
return Minimum::MIN(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||
|
||||
class DStDev extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DStDev extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::STDEV(
|
||||
return StandardDeviations::STDEV(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||
|
||||
class DStDevP extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DStDevP extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::STDEVP(
|
||||
return StandardDeviations::STDEVP(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||
|
||||
class DVar extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DVar extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::VARFunc(
|
||||
return Variances::VAR(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||
|
||||
class DVarP extends DatabaseAbstract
|
||||
{
|
||||
|
|
@ -39,7 +39,7 @@ class DVarP extends DatabaseAbstract
|
|||
return null;
|
||||
}
|
||||
|
||||
return Statistical::VARP(
|
||||
return Variances::VARP(
|
||||
self::getFilteredColumn($database, $field, $criteria)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1222,27 +1222,27 @@ class MathTrig
|
|||
$aArgs = self::filterFormulaArgs($cellReference, $aArgs);
|
||||
switch ($subtotal) {
|
||||
case 1:
|
||||
return Statistical::AVERAGE($aArgs);
|
||||
return Statistical\Averages::AVERAGE($aArgs);
|
||||
case 2:
|
||||
return Statistical::COUNT($aArgs);
|
||||
return Statistical\Counts::COUNT($aArgs);
|
||||
case 3:
|
||||
return Statistical::COUNTA($aArgs);
|
||||
return Statistical\Counts::COUNTA($aArgs);
|
||||
case 4:
|
||||
return Statistical::MAX($aArgs);
|
||||
return Statistical\Maximum::MAX($aArgs);
|
||||
case 5:
|
||||
return Statistical::MIN($aArgs);
|
||||
return Statistical\Minimum::MIN($aArgs);
|
||||
case 6:
|
||||
return self::PRODUCT($aArgs);
|
||||
case 7:
|
||||
return Statistical::STDEV($aArgs);
|
||||
return Statistical\StandardDeviations::STDEV($aArgs);
|
||||
case 8:
|
||||
return Statistical::STDEVP($aArgs);
|
||||
return Statistical\StandardDeviations::STDEVP($aArgs);
|
||||
case 9:
|
||||
return self::SUM($aArgs);
|
||||
case 10:
|
||||
return Statistical::VARFunc($aArgs);
|
||||
return Statistical\Variances::VAR($aArgs);
|
||||
case 11:
|
||||
return Statistical::VARP($aArgs);
|
||||
return Statistical\Variances::VARP($aArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,14 @@
|
|||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations;
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances;
|
||||
use PhpOffice\PhpSpreadsheet\Shared\Trend\Trend;
|
||||
|
||||
class Statistical
|
||||
|
|
@ -520,48 +526,6 @@ class Statistical
|
|||
return Functions::NULL();
|
||||
}
|
||||
|
||||
/**
|
||||
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
|
||||
* OpenOffice Calc always counts Booleans.
|
||||
* Gnumeric never counts Booleans.
|
||||
*
|
||||
* @param mixed $arg
|
||||
* @param mixed $k
|
||||
*
|
||||
* @return int|mixed
|
||||
*/
|
||||
private static function testAcceptedBoolean($arg, $k)
|
||||
{
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
|
||||
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $arg
|
||||
* @param mixed $k
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isAcceptedCountable($arg, $k)
|
||||
{
|
||||
if (
|
||||
((is_numeric($arg)) && (!is_string($arg))) ||
|
||||
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
|
||||
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* AVEDEV.
|
||||
*
|
||||
|
|
@ -571,45 +535,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* AVEDEV(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Averages::AVEDEV()
|
||||
* Use the AVEDEV() method in the Statistical\Averages class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function AVEDEV(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
// Return value
|
||||
$returnValue = 0;
|
||||
|
||||
$aMean = self::AVERAGE(...$args);
|
||||
if ($aMean === Functions::DIV0()) {
|
||||
return Functions::NAN();
|
||||
} elseif ($aMean === Functions::VALUE()) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
$returnValue += abs($arg - $aMean);
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount === 0) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
return $returnValue / $aCount;
|
||||
return Averages::AVEDEV(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -620,35 +557,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* AVERAGE(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Averages::AVERAGE()
|
||||
* Use the AVERAGE() method in the Statistical\Averages class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function AVERAGE(...$args)
|
||||
{
|
||||
$returnValue = $aCount = 0;
|
||||
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
$returnValue += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount > 0) {
|
||||
return $returnValue / $aCount;
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return Averages::AVERAGE(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -659,39 +579,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* AVERAGEA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Averages::AVERAGEA()
|
||||
* Use the AVERAGEA() method in the Statistical\Averages class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function AVERAGEA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
$aCount = 0;
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
$returnValue += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return $returnValue / $aCount;
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return Averages::AVERAGEA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -715,7 +614,7 @@ class Statistical
|
|||
*/
|
||||
public static function AVERAGEIF($range, $condition, $averageRange = [])
|
||||
{
|
||||
return Statistical\Conditional::AVERAGEIF($range, $condition, $averageRange);
|
||||
return Conditional::AVERAGEIF($range, $condition, $averageRange);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1026,27 +925,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* COUNT(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Counts::COUNT()
|
||||
* Use the COUNT() method in the Statistical\Counts class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNT(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Counts::COUNT(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1057,24 +947,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* COUNTA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Counts::COUNTA()
|
||||
* Use the COUNTA() method in the Statistical\Counts class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNTA(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Nulls are counted if literals, but not if cell values
|
||||
if ($arg !== null || (!Functions::isCellValue($k))) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Counts::COUNTA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1085,24 +969,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* COUNTBLANK(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Counts::COUNTBLANK()
|
||||
* Use the COUNTBLANK() method in the Statistical\Counts class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNTBLANK(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a blank cell?
|
||||
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Counts::COUNTBLANK(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1125,7 +1003,7 @@ class Statistical
|
|||
*/
|
||||
public static function COUNTIF($range, $condition)
|
||||
{
|
||||
return Statistical\Conditional::COUNTIF($range, $condition);
|
||||
return Conditional::COUNTIF($range, $condition);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1147,7 +1025,7 @@ class Statistical
|
|||
*/
|
||||
public static function COUNTIFS(...$args)
|
||||
{
|
||||
return Statistical\Conditional::COUNTIFS(...$args);
|
||||
return Conditional::COUNTIFS(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1325,7 +1203,7 @@ class Statistical
|
|||
// Return value
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = self::AVERAGE($aArgs);
|
||||
$aMean = Averages::AVERAGE($aArgs);
|
||||
if ($aMean != Functions::DIV0()) {
|
||||
$aCount = -1;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
|
|
@ -1711,8 +1589,8 @@ class Statistical
|
|||
|
||||
$aMean = MathTrig::PRODUCT($aArgs);
|
||||
if (is_numeric($aMean) && ($aMean > 0)) {
|
||||
$aCount = self::COUNT($aArgs);
|
||||
if (self::MIN($aArgs) > 0) {
|
||||
$aCount = Counts::COUNT($aArgs);
|
||||
if (Minimum::MIN($aArgs) > 0) {
|
||||
return $aMean ** (1 / $aCount);
|
||||
}
|
||||
}
|
||||
|
|
@ -1772,7 +1650,7 @@ class Statistical
|
|||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
if (self::MIN($aArgs) < 0) {
|
||||
if (Minimum::MIN($aArgs) < 0) {
|
||||
return Functions::NAN();
|
||||
}
|
||||
$aCount = 0;
|
||||
|
|
@ -1883,8 +1761,8 @@ class Statistical
|
|||
public static function KURT(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = self::AVERAGE($aArgs);
|
||||
$stdDev = self::STDEV($aArgs);
|
||||
$mean = Averages::AVERAGE($aArgs);
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
|
||||
if ($stdDev > 0) {
|
||||
$count = $summer = 0;
|
||||
|
|
@ -1941,7 +1819,7 @@ class Statistical
|
|||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
$count = self::COUNT($mArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
|
|
@ -2184,30 +2062,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* MAX(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Maximum::MAX()
|
||||
* Use the MAX() method in the Statistical\Maximum class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MAX(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Maximum::MAX(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2218,35 +2084,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* MAXA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Maximum::MAXA()
|
||||
* Use the MAXA() method in the Statistical\Maximum class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MAXA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Maximum::MAXA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2321,30 +2170,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* MIN(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Minimum::MIN()
|
||||
* Use the MIN() method in the Statistical\Minimum class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MIN(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Minimum::MIN(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2355,35 +2192,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* MINA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Minimum::MINA()
|
||||
* Use the MINA() method in the Statistical\Minimum class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MINA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Minimum::MINA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2688,7 +2508,7 @@ class Statistical
|
|||
$mValueCount = count($mArgs);
|
||||
if ($mValueCount > 0) {
|
||||
sort($mArgs);
|
||||
$count = self::COUNT($mArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
$index = $entry * ($count - 1);
|
||||
$iBase = floor($index);
|
||||
if ($index == $iBase) {
|
||||
|
|
@ -2775,7 +2595,7 @@ class Statistical
|
|||
*/
|
||||
public static function PERMUT($numObjs, $numInSet)
|
||||
{
|
||||
return Statistical\Permutations::PERMUT($numObjs, $numInSet);
|
||||
return Permutations::PERMUT($numObjs, $numInSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2930,8 +2750,8 @@ class Statistical
|
|||
public static function SKEW(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$mean = self::AVERAGE($aArgs);
|
||||
$stdDev = self::STDEV($aArgs);
|
||||
$mean = Averages::AVERAGE($aArgs);
|
||||
$stdDev = StandardDeviations::STDEV($aArgs);
|
||||
|
||||
$count = $summer = 0;
|
||||
// Loop through arguments
|
||||
|
|
@ -3015,7 +2835,7 @@ class Statistical
|
|||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
$count = self::COUNT($mArgs);
|
||||
$count = Counts::COUNT($mArgs);
|
||||
--$entry;
|
||||
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
|
||||
return Functions::NAN();
|
||||
|
|
@ -3065,45 +2885,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* STDEV(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\StandardDeviations::STDEV()
|
||||
* Use the STDEV() method in the Statistical\StandardDeviations class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function STDEV(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
// Return value
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = self::AVERAGE($aArgs);
|
||||
if ($aMean !== null) {
|
||||
$aCount = -1;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if ($returnValue === null) {
|
||||
$returnValue = ($arg - $aMean) ** 2;
|
||||
} else {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
}
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return StandardDeviations::STDEV(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3114,48 +2907,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* STDEVA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\StandardDeviations::STDEVA()
|
||||
* Use the STDEVA() method in the Statistical\StandardDeviations class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVA(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = self::AVERAGEA($aArgs);
|
||||
if ($aMean !== null) {
|
||||
$aCount = -1;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
if ($returnValue === null) {
|
||||
$returnValue = ($arg - $aMean) ** 2;
|
||||
} else {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
}
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return StandardDeviations::STDEVA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3166,43 +2929,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* STDEVP(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\StandardDeviations::STDEVP()
|
||||
* Use the STDEVP() method in the Statistical\StandardDeviations class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVP(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = self::AVERAGE($aArgs);
|
||||
if ($aMean !== null) {
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if ($returnValue === null) {
|
||||
$returnValue = ($arg - $aMean) ** 2;
|
||||
} else {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
}
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return StandardDeviations::STDEVP(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3213,48 +2951,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* STDEVPA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\StandardDeviations::STDEVPA()
|
||||
* Use the STDEVPA() method in the Statistical\StandardDeviations class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVPA(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$returnValue = null;
|
||||
|
||||
$aMean = self::AVERAGEA($aArgs);
|
||||
if ($aMean !== null) {
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
if ($returnValue === null) {
|
||||
$returnValue = ($arg - $aMean) ** 2;
|
||||
} else {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
}
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (($aCount > 0) && ($returnValue >= 0)) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
return StandardDeviations::STDEVPA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3472,14 +3180,14 @@ class Statistical
|
|||
$mArgs[] = $arg;
|
||||
}
|
||||
}
|
||||
$discard = floor(self::COUNT($mArgs) * $percent / 2);
|
||||
$discard = floor(Counts::COUNT($mArgs) * $percent / 2);
|
||||
sort($mArgs);
|
||||
for ($i = 0; $i < $discard; ++$i) {
|
||||
array_pop($mArgs);
|
||||
array_shift($mArgs);
|
||||
}
|
||||
|
||||
return self::AVERAGE($mArgs);
|
||||
return Averages::AVERAGE($mArgs);
|
||||
}
|
||||
|
||||
return Functions::VALUE();
|
||||
|
|
@ -3493,38 +3201,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* VAR(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*
|
||||
*@see Statistical\Variances::VAR()
|
||||
* Use the VAR() method in the Statistical\Variances class instead
|
||||
*/
|
||||
public static function VARFunc(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 1) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Variances::VAR(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3535,51 +3223,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* VARA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Variances::VARA()
|
||||
* Use the VARA() method in the Statistical\Variances class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARA(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_string($arg)) &&
|
||||
(Functions::isValue($k))
|
||||
) {
|
||||
return Functions::VALUE();
|
||||
} elseif (
|
||||
(is_string($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 1) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Variances::VARA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3590,39 +3245,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* VARP(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Variances::VARP()
|
||||
* Use the VARP() method in the Statistical\Variances class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARP(...$args)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Variances::VARP(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3633,51 +3267,18 @@ class Statistical
|
|||
* Excel Function:
|
||||
* VARPA(value1[,value2[, ...]])
|
||||
*
|
||||
* @Deprecated 1.17.0
|
||||
*
|
||||
* @see Statistical\Variances::VARPA()
|
||||
* Use the VARPA() method in the Statistical\Variances class instead
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARPA(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_string($arg)) &&
|
||||
(Functions::isValue($k))
|
||||
) {
|
||||
return Functions::VALUE();
|
||||
} elseif (
|
||||
(is_string($arg)) &&
|
||||
(!Functions::isMatrixValue($k))
|
||||
) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
$returnValue = ($summerA - $summerB) / ($aCount * $aCount);
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
return Variances::VARPA(...$args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3734,10 +3335,10 @@ class Statistical
|
|||
$sigma = Functions::flattenSingleValue($sigma);
|
||||
|
||||
if ($sigma === null) {
|
||||
$sigma = self::STDEV($dataSet);
|
||||
$sigma = StandardDeviations::STDEV($dataSet);
|
||||
}
|
||||
$n = count($dataSet);
|
||||
|
||||
return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
|
||||
return 1 - self::NORMSDIST((Averages::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
abstract class AggregateBase
|
||||
{
|
||||
/**
|
||||
* MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
|
||||
* OpenOffice Calc always counts Booleans.
|
||||
* Gnumeric never counts Booleans.
|
||||
*
|
||||
* @param mixed $arg
|
||||
* @param mixed $k
|
||||
*
|
||||
* @return int|mixed
|
||||
*/
|
||||
protected static function testAcceptedBoolean($arg, $k)
|
||||
{
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
|
||||
(Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $arg
|
||||
* @param mixed $k
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function isAcceptedCountable($arg, $k)
|
||||
{
|
||||
if (
|
||||
((is_numeric($arg)) && (!is_string($arg))) ||
|
||||
((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
|
||||
(Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Averages extends AggregateBase
|
||||
{
|
||||
/**
|
||||
* AVEDEV.
|
||||
*
|
||||
* Returns the average of the absolute deviations of data points from their mean.
|
||||
* AVEDEV is a measure of the variability in a data set.
|
||||
*
|
||||
* Excel Function:
|
||||
* AVEDEV(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function AVEDEV(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
// Return value
|
||||
$returnValue = 0;
|
||||
|
||||
$aMean = self::AVERAGE(...$args);
|
||||
if ($aMean === Functions::DIV0()) {
|
||||
return Functions::NAN();
|
||||
} elseif ($aMean === Functions::VALUE()) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
$returnValue += abs($arg - $aMean);
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount === 0) {
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
return $returnValue / $aCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* AVERAGE.
|
||||
*
|
||||
* Returns the average (arithmetic mean) of the arguments
|
||||
*
|
||||
* Excel Function:
|
||||
* AVERAGE(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function AVERAGE(...$args)
|
||||
{
|
||||
$returnValue = $aCount = 0;
|
||||
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
|
||||
return Functions::VALUE();
|
||||
}
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
$returnValue += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
if ($aCount > 0) {
|
||||
return $returnValue / $aCount;
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
/**
|
||||
* AVERAGEA.
|
||||
*
|
||||
* Returns the average of its arguments, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* AVERAGEA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function AVERAGEA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
$aCount = 0;
|
||||
// Loop through arguments
|
||||
foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
if (is_bool($arg)) {
|
||||
$arg = (int) $arg;
|
||||
} elseif (is_string($arg)) {
|
||||
$arg = 0;
|
||||
}
|
||||
$returnValue += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return $returnValue / $aCount;
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Counts extends AggregateBase
|
||||
{
|
||||
/**
|
||||
* COUNT.
|
||||
*
|
||||
* Counts the number of cells that contain numbers within the list of arguments
|
||||
*
|
||||
* Excel Function:
|
||||
* COUNT(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNT(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
$arg = self::testAcceptedBoolean($arg, $k);
|
||||
// Is it a numeric value?
|
||||
// Strings containing numeric values are only counted if they are string literals (not cell values)
|
||||
// and then only in MS Excel and in Open Office, not in Gnumeric
|
||||
if (self::isAcceptedCountable($arg, $k)) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* COUNTA.
|
||||
*
|
||||
* Counts the number of cells that are not empty within the list of arguments
|
||||
*
|
||||
* Excel Function:
|
||||
* COUNTA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNTA(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
// Nulls are counted if literals, but not if cell values
|
||||
if ($arg !== null || (!Functions::isCellValue($k))) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* COUNTBLANK.
|
||||
*
|
||||
* Counts the number of empty cells within the list of arguments
|
||||
*
|
||||
* Excel Function:
|
||||
* COUNTBLANK(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function COUNTBLANK(...$args)
|
||||
{
|
||||
$returnValue = 0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a blank cell?
|
||||
if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
|
||||
++$returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
abstract class MaxMinBase
|
||||
{
|
||||
protected static function datatypeAdjustmentAllowStrings($value)
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return (int) $value;
|
||||
} elseif (is_string($value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Maximum extends MaxMinBase
|
||||
{
|
||||
/**
|
||||
* MAX.
|
||||
*
|
||||
* MAX returns the value of the element of the values passed that has the highest value,
|
||||
* with negative numbers considered smaller than positive numbers.
|
||||
*
|
||||
* Excel Function:
|
||||
* MAX(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MAX(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* MAXA.
|
||||
*
|
||||
* Returns the greatest value in a list of arguments, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* MAXA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MAXA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
if (($returnValue === null) || ($arg > $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Minimum extends MaxMinBase
|
||||
{
|
||||
/**
|
||||
* MIN.
|
||||
*
|
||||
* MIN returns the value of the element of the values passed that has the smallest value,
|
||||
* with negative numbers considered smaller than positive numbers.
|
||||
*
|
||||
* Excel Function:
|
||||
* MIN(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MIN(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* MINA.
|
||||
*
|
||||
* Returns the smallest value in a list of arguments, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* MINA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public static function MINA(...$args)
|
||||
{
|
||||
$returnValue = null;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
foreach ($aArgs as $arg) {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
if (($returnValue === null) || ($arg < $returnValue)) {
|
||||
$returnValue = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnValue === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class StandardDeviations extends VarianceBase
|
||||
{
|
||||
/**
|
||||
* STDEV.
|
||||
*
|
||||
* Estimates standard deviation based on a sample. The standard deviation is a measure of how
|
||||
* widely values are dispersed from the average value (the mean).
|
||||
*
|
||||
* Excel Function:
|
||||
* STDEV(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string The result, or a string containing an error
|
||||
*/
|
||||
public static function STDEV(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$aMean = Averages::AVERAGE($aArgs);
|
||||
|
||||
if (!is_string($aMean)) {
|
||||
$returnValue = 0.0;
|
||||
$aCount = -1;
|
||||
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
/**
|
||||
* STDEVA.
|
||||
*
|
||||
* Estimates standard deviation based on a sample, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* STDEVA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVA(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$aMean = Averages::AVERAGEA($aArgs);
|
||||
|
||||
if (!is_string($aMean)) {
|
||||
$returnValue = 0.0;
|
||||
$aCount = -1;
|
||||
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
/**
|
||||
* STDEVP.
|
||||
*
|
||||
* Calculates standard deviation based on the entire population
|
||||
*
|
||||
* Excel Function:
|
||||
* STDEVP(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVP(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$aMean = Averages::AVERAGE($aArgs);
|
||||
|
||||
if (!is_string($aMean)) {
|
||||
$returnValue = 0.0;
|
||||
$aCount = 0;
|
||||
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if (
|
||||
(is_bool($arg)) &&
|
||||
((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
|
||||
) {
|
||||
$arg = (int) $arg;
|
||||
}
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
|
||||
/**
|
||||
* STDEVPA.
|
||||
*
|
||||
* Calculates standard deviation based on the entire population, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* STDEVPA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string
|
||||
*/
|
||||
public static function STDEVPA(...$args)
|
||||
{
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
|
||||
$aMean = Averages::AVERAGEA($aArgs);
|
||||
|
||||
if (!is_string($aMean)) {
|
||||
$returnValue = 0.0;
|
||||
$aCount = 0;
|
||||
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
$returnValue += ($arg - $aMean) ** 2;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
return sqrt($returnValue / $aCount);
|
||||
}
|
||||
}
|
||||
|
||||
return Functions::DIV0();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
abstract class VarianceBase
|
||||
{
|
||||
protected static function datatypeAdjustmentAllowStrings($value)
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return (int) $value;
|
||||
} elseif (is_string($value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected static function datatypeAdjustmentBooleans($value)
|
||||
{
|
||||
if (is_bool($value)) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
|
||||
|
||||
class Variances extends VarianceBase
|
||||
{
|
||||
/**
|
||||
* VAR.
|
||||
*
|
||||
* Estimates variance based on a sample.
|
||||
*
|
||||
* Excel Function:
|
||||
* VAR(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VAR(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0.0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
$arg = self::datatypeAdjustmentBooleans($arg);
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 1) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
|
||||
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* VARA.
|
||||
*
|
||||
* Estimates variance based on a sample, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* VARA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARA(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0.0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_string($arg)) && (Functions::isValue($k))) {
|
||||
return Functions::VALUE();
|
||||
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 1) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
|
||||
return ($summerA - $summerB) / ($aCount * ($aCount - 1));
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* VARP.
|
||||
*
|
||||
* Calculates variance based on the entire population
|
||||
*
|
||||
* Excel Function:
|
||||
* VARP(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARP(...$args)
|
||||
{
|
||||
// Return value
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0.0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArray($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $arg) {
|
||||
$arg = self::datatypeAdjustmentBooleans($arg);
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) && (!is_string($arg))) {
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
|
||||
return ($summerA - $summerB) / ($aCount * $aCount);
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* VARPA.
|
||||
*
|
||||
* Calculates variance based on the entire population, including numbers, text, and logical values
|
||||
*
|
||||
* Excel Function:
|
||||
* VARPA(value1[,value2[, ...]])
|
||||
*
|
||||
* @param mixed ...$args Data values
|
||||
*
|
||||
* @return float|string (string if result is an error)
|
||||
*/
|
||||
public static function VARPA(...$args)
|
||||
{
|
||||
$returnValue = Functions::DIV0();
|
||||
|
||||
$summerA = $summerB = 0.0;
|
||||
|
||||
// Loop through arguments
|
||||
$aArgs = Functions::flattenArrayIndexed($args);
|
||||
$aCount = 0;
|
||||
foreach ($aArgs as $k => $arg) {
|
||||
if ((is_string($arg)) && (Functions::isValue($k))) {
|
||||
return Functions::VALUE();
|
||||
} elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
|
||||
} else {
|
||||
// Is it a numeric value?
|
||||
if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
|
||||
$arg = self::datatypeAdjustmentAllowStrings($arg);
|
||||
$summerA += ($arg * $arg);
|
||||
$summerB += $arg;
|
||||
++$aCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCount > 0) {
|
||||
$summerA *= $aCount;
|
||||
$summerB *= $summerB;
|
||||
|
||||
return ($summerA - $summerB) / ($aCount * $aCount);
|
||||
}
|
||||
|
||||
return $returnValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ class Tcpdf extends Pdf
|
|||
*
|
||||
* @param string $orientation Page orientation
|
||||
* @param string $unit Unit measure
|
||||
* @param string $paperSize Paper size
|
||||
* @param array|string $paperSize Paper size
|
||||
*
|
||||
* @return \TCPDF implementation
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StDevATest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerSTDEVA
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testSTDEVA($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::STDEVA($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSTDEVA()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/STDEVA.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StDevPATest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerSTDEVPA
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testSTDEVPA($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::STDEVPA($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSTDEVPA()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/STDEVPA.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StDevPTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerSTDEVP
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testSTDEVP($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::STDEVP($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSTDEVP()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/STDEVP.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class StDevTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerSTDEV
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testSTDEV($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::STDEV($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerSTDEV()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/STDEV.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class VarATest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerVARA
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testVARA($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::VARA($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerVARA()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/VARA.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class VarPATest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerVARPA
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testVARPA($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::VARPA($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerVARPA()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/VARPA.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class VarPTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerVARP
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testVARP($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::VARP($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerVARP()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/VARP.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical;
|
||||
|
||||
use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class VarTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerVAR
|
||||
*
|
||||
* @param mixed $expectedResult
|
||||
* @param mixed $values
|
||||
*/
|
||||
public function testVAR($expectedResult, $values): void
|
||||
{
|
||||
$result = Statistical::VARFunc($values);
|
||||
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
|
||||
}
|
||||
|
||||
public function providerVAR()
|
||||
{
|
||||
return require 'tests/data/Calculation/Statistical/VAR.php';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
27.463915719843,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
[
|
||||
'#DIV/0!',
|
||||
['A', 'B', 'C'],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
27.463915719843,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
[
|
||||
'#DIV/0!',
|
||||
[],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
26.0545581424825,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
[
|
||||
'#DIV/0!',
|
||||
['A', 'B', 'C'],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
26.0545581424825,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
[
|
||||
'#DIV/0!',
|
||||
[],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
754.266666666667,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
754.266666666667,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
678.84,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
];
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
[
|
||||
678.84,
|
||||
[1345, 1301, 1368, 1322, 1310, 1370, 1318, 1350, 1303, 1299],
|
||||
],
|
||||
];
|
||||
Loading…
Reference in New Issue