public static function oneWay(array ...$samples)
{
// Must have at least three samples
$m = count($samples);
if ($m < 3) {
throw new Exception\BadDataException('Must have at least three samples');
}
// All samples must have the same number of items
$n = count($samples[0]);
for ($i = 1; $i < $m; $i++) {
if (count($samples[$i]) !== $n) {
throw new Exception\BadDataException('All samples must have the same number of values');
}
}
// Summary data for each sample
$summary_data = [];
foreach ($samples as $i => $sample) {
$summary_data[$i] = [];
$summary_data[$i]['n'] = $n;
$summary_data[$i]['sum'] = array_sum($sample);
$summary_data[$i]['mean'] = Average::mean($sample);
$summary_data[$i]['SS'] = RandomVariable::sumOfSquares($sample);
$summary_data[$i]['variance'] = Descriptive::sampleVariance($sample);
$summary_data[$i]['sd'] = Descriptive::sd($sample);
$summary_data[$i]['sem'] = RandomVariable::standardErrorOfTheMean($sample);
}
// Totals summary
$all_elements = array_reduce($samples, function ($merged, $sample) {
return array_merge($merged, $sample);
}, array());
$μ = Average::mean($all_elements);
$total = ['n' => count($all_elements), 'sum' => array_sum($all_elements), 'mean' => $μ, 'SS' => RandomVariable::sumOfSquares($all_elements), 'variance' => Descriptive::sampleVariance($all_elements), 'sd' => Descriptive::sd($all_elements), 'sem' => RandomVariable::standardErrorOfTheMean($all_elements)];
// ANOVA sum of squares
$SST = RandomVariable::sumOfSquaresDeviations($all_elements);
$SSB = array_sum(array_map(function ($sample) use($n, $μ) {
return $n * (Average::mean($sample) - $μ) ** 2;
}, $samples));
$SSW = array_sum(array_map('MathPHP\\Statistics\\RandomVariable::sumOfSquaresDeviations', $samples));
// ANOVA degrees of freedom
$dfT = $m * $n - 1;
$dfB = $m - 1;
$dfW = $m * ($n - 1);
// ANOVA mean squares
$MSB = $SSB / $dfB;
$MSW = $SSW / $dfW;
// Test statistics
$F = $MSB / $MSW;
$P = F::above($F, $dfB, $dfW);
// Return ANOVA report
return ['ANOVA' => ['treatment' => ['SS' => $SSB, 'df' => $dfB, 'MS' => $MSB, 'F' => $F, 'P' => $P], 'error' => ['SS' => $SSW, 'df' => $dfW, 'MS' => $MSW], 'total' => ['SS' => $SST, 'df' => $dfT]], 'total_summary' => $total, 'data_summary' => $summary_data];
}