FLIGNER
Overview
The FLIGNER
function performs the Fligner-Killeen test for equality of variances across multiple sample groups. This non-parametric test is robust to departures from normality and is useful for comparing the spread of data in more than two groups, unlike parametric tests such as the F-test which assume normality. The test statistic is based on ranks and can use different measures of central tendency (mean, median, or trimmed mean):
where is the size of group , is the average rank for group , and is the overall average rank. For more details, see the scipy.stats.fligner documentation .
This wrapper simplifies the function to only the most commonly used parameters: samples
, center
, and (optionally) trimmed_proportion
if center
is set to trimmed
. 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:
=FLIGNER(samples, [center], [trimmed_proportion])
samples
(2D list, required): Each column is a sample group. Must have at least two columns and each column must be a non-empty list of numbers.center
(string, optional, default='median'
): Central tendency function to use. One of'mean'
,'median'
, or'trimmed'
.trimmed_proportion
(float, optional, required only ifcenter
is'trimmed'
): Proportion to cut from each end when using trimmed mean. Must be between0
and<0.5
.
The function returns a single-row 2D list: [statistic, pvalue]
, or an error message (string) if the input is invalid. The statistic measures the evidence against the null hypothesis (equal variances), and the p-value indicates the probability of observing such a statistic under the null hypothesis.
Examples
Example 1: Basic Case (Median Center)
Inputs:
samples | center | ||
---|---|---|---|
1.2 | 2.5 | 1.9 | median |
2.3 | 2.7 | 2.0 | |
2.1 | 2.8 | 2.2 |
Excel formula:
=FLIGNER({1.2,2.5,1.9;2.3,2.7,2.0;2.1,2.8,2.2}, "median")
Expected output:
statistic | pvalue |
---|---|
0.516 | 0.772 |
Example 2: Mean Center
Inputs:
samples | center | ||
---|---|---|---|
1.2 | 2.5 | 1.9 | mean |
2.3 | 2.7 | 2.0 | |
2.1 | 2.8 | 2.2 |
Excel formula:
=FLIGNER({1.2,2.5,1.9;2.3,2.7,2.0;2.1,2.8,2.2}, "mean")
Expected output:
statistic | pvalue |
---|---|
5.859 | 0.053 |
Example 3: Trimmed Center (0.1 Proportion)
Inputs:
samples | center | trimmed_proportion | ||
---|---|---|---|---|
1.2 | 2.5 | 1.9 | trimmed | 0.1 |
2.3 | 2.7 | 2.0 | ||
2.1 | 2.8 | 2.2 |
Excel formula:
=FLIGNER({1.2,2.5,1.9;2.3,2.7,2.0;2.1,2.8,2.2}, "trimmed", 0.1)
Expected output:
statistic | pvalue |
---|---|
5.859 | 0.053 |
Example 4: Different Values (Median Center)
Inputs:
samples | center | ||
---|---|---|---|
1.0 | 2.0 | 3.0 | median |
1.1 | 2.1 | 3.1 | |
1.2 | 2.2 | 3.2 |
Excel formula:
=FLIGNER({1.0,2.0,3.0;1.1,2.1,3.1;1.2,2.2,3.2}, "median")
Expected output:
statistic | pvalue |
---|---|
0.391 | 0.822 |
Python Code
from scipy.stats import fligner as scipy_fligner
from typing import List, Optional, Union
def fligner(samples: List[List[float]], center: str = 'median', trimmed_proportion: Optional[float] = None) -> Union[List[List[float]], str]:
"""
Performs the Fligner-Killeen test for equality of variances across multiple samples.
Args:
samples: 2D list of float values. Each column represents a sample group.
center: Function of central tendency to use ('mean', 'median', 'trimmed'). Default is 'median'.
trimmed_proportion: Proportion to cut from each end when center is 'trimmed'. Optional.
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 samples
if not isinstance(samples, list) or len(samples) < 2:
return "Invalid input: samples must be a 2D list with at least two columns (sample groups)."
if not all(isinstance(col, list) and len(col) > 0 for col in samples):
return "Invalid input: each sample group must be a non-empty list."
# Transpose if rows are samples (Excel usually passes columns as samples)
if len(samples) > 0 and len(samples[0]) > 0 and all(isinstance(x, (int, float)) for x in samples[0]):
# Assume columns are samples
sample_groups = samples
else:
return "Invalid input: samples must be a 2D list of floats, each column a sample group."
# Validate center
if center not in ('mean', 'median', 'trimmed'):
return "Invalid input: center must be 'mean', 'median', or 'trimmed'."
# Validate trimmed_proportion
if center == 'trimmed':
if trimmed_proportion is None:
return "Invalid input: trimmed_proportion must be specified when center is 'trimmed'."
try:
proportiontocut = float(trimmed_proportion)
except Exception:
return "Invalid input: trimmed_proportion must be a float."
if not (0 <= proportiontocut < 0.5):
return "Invalid input: trimmed_proportion must be between 0 and 0.5."
else:
proportiontocut = None
# Run test
try:
if center == 'trimmed':
stat, pvalue = scipy_fligner(*sample_groups, center=center, proportiontocut=proportiontocut)
else:
stat, pvalue = scipy_fligner(*sample_groups, center=center)
except Exception as e:
return f"scipy.stats.fligner error: {e}"
# Convert numpy types to Python float
try:
stat = float(stat)
pvalue = float(pvalue)
except Exception:
return "Invalid output: could not convert result to float."
# Validate output
if any([
not isinstance(stat, (int, float)),
not isinstance(pvalue, (int, float)),
stat is None or pvalue is None
]):
return "Invalid output from scipy.stats.fligner."
# Disallow nan/inf
import math
if any([math.isnan(stat), math.isnan(pvalue), math.isinf(stat), math.isinf(pvalue)]):
return "Invalid output: statistic or pvalue is nan or inf."
return [[stat, pvalue]]