FRIEDMANCHISQUARE
Overview
The FRIEDMANCHISQUARE
function performs the Friedman test for repeated measures, a nonparametric statistical test used to detect differences in treatments across multiple test attempts. It is commonly used when the same subjects are measured under different conditions, and the data are organized in blocks (rows) and treatments (columns). The test ranks the values within each block and compares the sums of ranks across treatments.
The test statistic is calculated as:
where is the number of blocks (rows), is the number of treatments (columns), and is the sum of ranks for treatment . For more details, see the scipy.stats.friedmanchisquare documentation .
This wrapper simplifies the function to accept only a single 2D array of samples, with each column as a treatment and each row as a block. Parameters such as axis
, nan_policy
, and keepdims
are omitted for Excel compatibility. This example function is provided as-is without any representation of accuracy.
Usage
To use the function in Excel:
=FRIEDMANCHISQUARE(samples)
samples
(2D list, required): Table of numeric values, where each column is a treatment (sample) and each row is a block (observation). Must have at least three columns and at least two rows per column. All columns must have the same number of rows.
The function returns a single-row 2D array: [statistic, pvalue]
(both float), or an error message (string) if the input is invalid.
Examples
Example 1: Basic Case
Inputs:
samples | ||
---|---|---|
10 | 20 | 30 |
20 | 20 | 20 |
30 | 10 | 20 |
Excel formula:
=FRIEDMANCHISQUARE({10,20,30;20,20,20;30,10,20})
Expected output:
statistic | pvalue |
---|---|
0.200 | 0.905 |
Example 2: Four Samples
Inputs:
samples | |||
---|---|---|---|
10 | 20 | 30 | 40 |
20 | 20 | 20 | 20 |
30 | 10 | 20 | 30 |
40 | 30 | 20 | 10 |
Excel formula:
=FRIEDMANCHISQUARE({10,20,30,40;20,20,20,20;30,10,20,30;40,30,20,10})
Expected output:
statistic | pvalue |
---|---|
1.114 | 0.774 |
Example 3: All Equal Values
Inputs:
samples | ||
---|---|---|
1 | 1 | 1 |
1 | 1 | 1 |
1 | 1 | 1 |
Excel formula:
=FRIEDMANCHISQUARE({1,1,1;1,1,1;1,1,1})
Expected output:
Result |
---|
Invalid output: statistic or pvalue is nan or inf. |
Example 4: Different Values
Inputs:
samples | ||
---|---|---|
5 | 10 | 15 |
10 | 5 | 10 |
15 | 10 | 5 |
Excel formula:
=FRIEDMANCHISQUARE({5,10,15;10,5,10;15,10,5})
Expected output:
statistic | pvalue |
---|---|
0.545 | 0.761 |
Python Code
from scipy.stats import friedmanchisquare as scipy_friedmanchisquare
from typing import List, Union
def friedmanchisquare(samples: List[List[float]]) -> Union[List[List[float]], str]:
"""
Computes the Friedman test for repeated samples.
Args:
samples: 2D list of float values. Each column represents a sample, and each row an observation. At least three columns (samples) are required, and all columns must have the same number of rows.
Returns:
2D list with a single row: [statistic, pvalue], or an error message (str) if input is invalid.
This example function is provided as-is without any representation of accuracy.
"""
# Validate input type
if not isinstance(samples, list) or not samples or not all(isinstance(col, list) for col in samples):
return "Invalid input: samples must be a 2D list with at least three columns."
n_cols = len(samples)
if n_cols < 3:
return "Invalid input: samples must have at least three columns (samples)."
n_rows = [len(col) for col in samples]
if len(set(n_rows)) != 1:
return "Invalid input: all columns must have the same number of rows."
if n_rows[0] < 2:
return "Invalid input: each column must have at least two rows."
# Check for non-numeric values
try:
for col in samples:
for val in col:
if not isinstance(val, (int, float)):
return "Invalid input: all values must be numeric."
except Exception:
return "Invalid input: could not parse values as numeric."
# Transpose to match scipy's expected input (each argument is a sample)
try:
args = [list(col) for col in samples]
stat, pvalue = scipy_friedmanchisquare(*args)
# Convert to native float if needed
stat = float(stat)
pvalue = float(pvalue)
# Check for nan/inf
if any(
(isinstance(x, float) and (x != x or x == float('inf') or x == float('-inf')))
for x in [stat, pvalue]
):
return "Invalid output: statistic or pvalue is nan or inf."
return [[stat, pvalue]]
except Exception as e:
return f"scipy.stats.friedmanchisquare error: {e}"