PAIRWISE_TUKEY
Tukey’s Honestly Significant Difference procedure performs pairwise group-mean comparisons while controlling the family-wise error rate.
It evaluates all group pairs after one-way designs and reports adjusted significance outcomes, confidence intervals, and effect-size statistics.
This wrapper accepts a table with headers and returns Pingouin’s Tukey comparison table.
Excel Usage
=PAIRWISE_TUKEY(data, dv, between, effsize)
data(list[list], required): Input table where the first row contains column names.dv(str, required): Name of the dependent-variable column.between(str, required): Name of the grouping column.effsize(str, optional, default: “hedges”): Effect size metric for pairwise contrasts.
Returns (list[list]): 2D table containing Tukey pairwise comparison results.
Example 1: Pairwise comparisons across three groups
Inputs:
| data | dv | between | |
|---|---|---|---|
| score | grp | score | grp |
| 5.1 | A | ||
| 5.3 | A | ||
| 5.2 | A | ||
| 6 | B | ||
| 6.2 | B | ||
| 6.1 | B | ||
| 7 | C | ||
| 7.1 | C | ||
| 7.2 | C |
Excel formula:
=PAIRWISE_TUKEY({"score","grp";5.1,"A";5.3,"A";5.2,"A";6,"B";6.2,"B";6.1,"B";7,"C";7.1,"C";7.2,"C"}, "score", "grp")
Expected output:
| A | B | mean_A | mean_B | diff | se | T | p_tukey | hedges |
|---|---|---|---|---|---|---|---|---|
| A | B | 5.2 | 6.1 | -0.9 | 0.0816497 | -11.0227 | 0.0000818439 | -7.2 |
| A | C | 5.2 | 7.1 | -1.9 | 0.0816497 | -23.2702 | 0.00000102587 | -15.2 |
| B | C | 6.1 | 7.1 | -1 | 0.0816497 | -12.2474 | 0.0000446025 | -8 |
Example 2: Cohen effect size in Tukey table
Inputs:
| data | dv | between | effsize | |
|---|---|---|---|---|
| y | treatment | y | treatment | cohen |
| 10.2 | T1 | |||
| 10.1 | T1 | |||
| 11 | T2 | |||
| 11.2 | T2 | |||
| 12.1 | T3 | |||
| 12 | T3 |
Excel formula:
=PAIRWISE_TUKEY({"y","treatment";10.2,"T1";10.1,"T1";11,"T2";11.2,"T2";12.1,"T3";12,"T3"}, "y", "treatment", "cohen")
Expected output:
| A | B | mean_A | mean_B | diff | se | T | p_tukey | cohen |
|---|---|---|---|---|---|---|---|---|
| T1 | T2 | 10.15 | 11.1 | -0.95 | 0.1 | -9.5 | 0.00507011 | -8.49706 |
| T1 | T3 | 10.15 | 12.05 | -1.9 | 0.1 | -19 | 0.000655583 | -26.8701 |
| T2 | T3 | 11.1 | 12.05 | -0.95 | 0.1 | -9.5 | 0.00507011 | -8.49706 |
Example 3: Four-group balanced dataset
Inputs:
| data | dv | between | |
|---|---|---|---|
| metric | g | metric | g |
| 1.1 | G1 | ||
| 1.2 | G1 | ||
| 2 | G2 | ||
| 2.1 | G2 | ||
| 2.9 | G3 | ||
| 3 | G3 | ||
| 4 | G4 | ||
| 4.1 | G4 |
Excel formula:
=PAIRWISE_TUKEY({"metric","g";1.1,"G1";1.2,"G1";2,"G2";2.1,"G2";2.9,"G3";3,"G3";4,"G4";4.1,"G4"}, "metric", "g")
Expected output:
| A | B | mean_A | mean_B | diff | se | T | p_tukey | hedges |
|---|---|---|---|---|---|---|---|---|
| G1 | G2 | 1.15 | 2.05 | -0.9 | 0.0707107 | -12.7279 | 0.000770909 | -7.2731 |
| G1 | G3 | 1.15 | 2.95 | -1.8 | 0.0707107 | -25.4558 | 0.0000499777 | -14.5462 |
| G1 | G4 | 1.15 | 4.05 | -2.9 | 0.0707107 | -41.0122 | 0.0000074742 | -23.4355 |
| G2 | G3 | 2.05 | 2.95 | -0.9 | 0.0707107 | -12.7279 | 0.000770909 | -7.2731 |
| G2 | G4 | 2.05 | 4.05 | -2 | 0.0707107 | -28.2843 | 0.0000328672 | -16.1624 |
| G3 | G4 | 2.95 | 4.05 | -1.1 | 0.0707107 | -15.5563 | 0.000351055 | -8.88934 |
Example 4: Small mean separation among groups
Inputs:
| data | dv | between | |
|---|---|---|---|
| result | condition | result | condition |
| 20 | C1 | ||
| 20.2 | C1 | ||
| 20.4 | C2 | ||
| 20.5 | C2 | ||
| 20.8 | C3 | ||
| 20.9 | C3 |
Excel formula:
=PAIRWISE_TUKEY({"result","condition";20,"C1";20.2,"C1";20.4,"C2";20.5,"C2";20.8,"C3";20.9,"C3"}, "result", "condition")
Expected output:
| A | B | mean_A | mean_B | diff | se | T | p_tukey | hedges |
|---|---|---|---|---|---|---|---|---|
| C1 | C2 | 20.1 | 20.45 | -0.35 | 0.1 | -3.5 | 0.0781827 | -1.78885 |
| C1 | C3 | 20.1 | 20.85 | -0.75 | 0.1 | -7.5 | 0.0100322 | -3.83326 |
| C2 | C3 | 20.45 | 20.85 | -0.4 | 0.1 | -4 | 0.0559553 | -3.23249 |
Python Code
import pandas as pd
from pingouin import pairwise_tukey as pg_pairwise_tukey
def pairwise_tukey(data, dv, between, effsize='hedges'):
"""
Run Tukey HSD pairwise comparisons using Pingouin.
See: https://pingouin-stats.org/build/html/generated/pingouin.pairwise_tukey.html
This example function is provided as-is without any representation of accuracy.
Args:
data (list[list]): Input table where the first row contains column names.
dv (str): Name of the dependent-variable column.
between (str): Name of the grouping column.
effsize (str, optional): Effect size metric for pairwise contrasts. Default is 'hedges'.
Returns:
list[list]: 2D table containing Tukey pairwise comparison results.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
def build_dataframe(table):
table = to2d(table)
if not isinstance(table, list) or not table or not all(isinstance(row, list) for row in table):
return None, "Error: data must be a non-empty 2D list"
if len(table) < 2:
return None, "Error: data must include a header row and at least one data row"
headers = [str(h).strip() for h in table[0]]
if any(h == "" for h in headers):
return None, "Error: header row contains empty column names"
if len(set(headers)) != len(headers):
return None, "Error: header row contains duplicate column names"
rows = []
for row in table[1:]:
if len(row) != len(headers):
return None, "Error: all data rows must match header width"
rows.append([None if cell == "" else cell for cell in row])
return pd.DataFrame(rows, columns=headers), None
def dataframe_to_2d(df):
out = [list(df.columns)]
for values in df.itertuples(index=False, name=None):
row = []
for value in values:
if pd.isna(value):
row.append("")
elif isinstance(value, bool):
row.append(value)
elif isinstance(value, (int, float)):
row.append(float(value))
else:
row.append(str(value))
out.append(row)
return out
frame, error = build_dataframe(data)
if error:
return error
if dv not in frame.columns:
return f"Error: dv column '{dv}' not found"
if between not in frame.columns:
return f"Error: between column '{between}' not found"
result = pg_pairwise_tukey(data=frame, dv=dv, between=between, effsize=effsize)
return dataframe_to_2d(result)
except Exception as e:
return f"Error: {str(e)}"Online Calculator
Input table where the first row contains column names.
Name of the dependent-variable column.
Name of the grouping column.
Effect size metric for pairwise contrasts.