STATS_MANN_WHITNEY – Mann–Whitney U test in Google Sheets™
What it does
Mann–Whitney U test for two independent samples — the rank replacement for STATS_INDEPENDENT when the data are not normal (see STATS_NORMALITY), are ranks or rating scales (1–5), or have outliers.
The first two columns of colFilter are the two samples, each with its own missing values; further columns are dropped, as in the t-tests.
Numbers as SPSS: U is the smaller of the two U values, Wilcoxon W the rank sum of the group that U belongs to, Z with the tie correction and without the continuity correction (scipy.stats.mannwhitneyu applies it by default and gives other numbers).
alternative "greater": the first column tends to be larger than the second; "less": smaller. The labels say (2-tailed) or (1-tailed).
The row "Exact Sig." is there only when the data have no ties and n1·n2 ≤ 400; otherwise the block is one row shorter (with ties only the asymptotic p, which corrects for them, is exact enough). As data accumulate the block can lose this row, never gain it.
Text with value labels is ranked by its codes — the labels give the order, so an ordinal scale ("low:1,mid:2,high:3") is a natural input.
Syntax
=STATS_MANN_WHITNEY(columns, colFilter, alternative)Parameters
columns — required
Cell range with data, e.g., A1:D100 or A:D.
Usually the first row should contain column names.
You can also add labels as the first row and column names as the second row.
Labels should use formats like "male:1,female:2" or "low:1:3,mid:3:5,high:5:7".
Examples:
A1:D100— use 4 columnsA1:C200— use 3 columnsA:F— use 6 columnsA1:D100 where row 1 contains labels and row 2 contains column names— use labels from the sheet
If every non-empty cell of the first row holds at least two label rules ("low:1,high:2"), it is the labels row, and the next row holds the column names; an empty cell there is a column without labels.
One rule in a cell ("yes:1") is read as a name, so a header such as "T:1", "Ratio 1:2" or "Note:" stays the names row. Give such a column a second rule, or pass one label in the labels parameter, where one rule is valid.
If the first row contains ordinary text, it is treated as the column names row as before.
A number, a date or a checkbox in the names row is a name: 2025, 2025-01-01, TRUE.
Column names must be unique: two identical headers are an error "Duplicate column name: x".
Every column with values needs a name: an empty header cell over values is an error "The name of column 2 is empty: a column with values needs a name", even when colFilter does not select that column. A column with neither a name nor values (the empty right edge of a range such as A:Z) is dropped without an error.
Column names that start with "#" are reserved/unsupported in filters, because "#" is used for index-based colFilter rules (for example #1, #2-#5).
What counts as a number (the same in every function):
- A column is numeric when it holds more numbers than text; with as many texts as numbers, or more, it is a text column.
- Every cell is typed by itself: a number written as text ('10', '007') is the number, a checkbox is 1 (checked) or 0 (unchecked). The texts 'TRUE'/'FALSE' stay text.
- A cell that does not match the type of its own column (text in a numeric column, a number in a text column) is missing for calculations and is counted in missing.
- An empty cell is a missing answer; the sign "." means "not applicable" — it is not a missing answer, not a category and not counted in missing.
- A text column with value labels (a labels row above the names) is analysed by the codes of its labels. A text column without labels is not analysed as numbers: lists of columns skip it with a note, tests on a pair of columns and models show an error.
An empty tail of the range (rows below the data) is dropped — only blank cells make it: a row of "." at the end stays and counts as not applicable, as in the middle. A column with neither a name nor values is dropped; a named empty column stays.
colFilter — optional, default "*"
Comma-separated column selector.
Use names ("age,score"), negative rules ("-id,-note"), a regex ("/^q/"), or index rules ("#N", "#A-#B", "-#N", "-#A-#B").
Case-sensitive; flags are not supported.
A name that does not exist is an error: "Column nope does not exist" (excluding it, "-nope", is ignored). Empty — all columns ("*").
Examples:
"age,score"— Names only (include only "age" and "score")"-id,-group"— Exclude some (include all except "id" and "group")"/^q/"— Regex only (all starts with "q")"#1,#3-#5"— Index include rules (first, and range 3..5)"-#1,-#3-#4"— Index exclude rules (drop first and 3..4)"age,#2-#4,-#3"— Mixed name/index rules with deterministic order"age,/^q/,-q5"— Mixed (include age, all starts with "q" except "q5")"/^x1{1,2}$/"— Regex with a comma inside: x1 and x11
Choose which columns from columns to use - a comma-separated string of rules.
⚙️ Four rule types (you can mix them):
- By name - exact header text (case-sensitive)
- "age,score,total"
- Negative rules - exclude by name (prefix with
-)- "-id,-notes" (include all except
idandnotes)
- "-id,-notes" (include all except
- Regex - a regular expression between slashes
/.../- "/^q/" (all headers starting with
q), "/(score|age)/", "/^x1{1,2}$/" (commas inside /.../ do not split the filter) - ❗— case-sensitive
- ❗— flags are not supported.
- "/^q/" (all headers starting with
- Index rules - position-based rules with
#- "#1" (first selected column), "#2-#5" (range), "-#1", "-#2-#4"
"*" alone selects every column; it cannot be combined with other rules ("*,-id" is an error) — write "-id" instead.
Rules are applied in the written order, and the selected columns keep that order ("/^q/,-q5,age" puts age last).
Index rules count the columns of the range: "#1" is its first column.
A name that does not exist is an error: "Column nope does not exist" — also in colName, yName, steps, rowCol, colCol and colNameForSplit. Excluding a name that does not exist ("-nope") is ignored.
A filter that selects no column — a regex without a match ("/^Q/" where the columns are q1, q2), index rules past the end, exclusions that remove every column — is an error that names the filter and the columns of the range: colFilter "/^Q/" selects no columns (columns: q1, q2, t). Empty and "*" select every column.
In STATS_ANALYZE, a regex with brackets or | needs the new syntax: PEARSON('/(score|age)/').
A colFilter saved in Settings applies to every formula without its own filter: on a range without those columns the formula shows the error above.
# prefix is reserved for index syntax and is not treated as a column-name filter token.
colFilter applies to all expressions in query. It does not create separate groups per expression.
alternative — optional, default "two-sided"
Alternative hypothesis for two-sample/one-sample tests and correlations: "two-sided", "greater" or "less"; 1 and -1 (number or text) mean greater and less.
Case and spaces around do not matter ("Greater", " less "). Another value is an error: alternative must be two-sided, greater or less (or 1, -1), got "grater". Empty — the default from Settings.
A one-sided hypothesis gives a one-sided interval: [lower, ∞) for greater, (−∞, upper] for less (for correlations [lower, 1] and [−1, upper]).
Allowed values: "two-sided", "greater", "less"
Examples:
"two-sided""greater""less"
Examples
- — the sample data (50 rows) all examples use
- — two-sided
=STATS_MANN_WHITNEY(Data!A1:T51, "before,after") - — one-sided: x1 tends to be larger
=STATS_MANN_WHITNEY(Data!A1:T51, "x1,x2", "greater")
What the result contains
A report that spills below the formula cell:
- the title "Mann-Whitney U Test (two-sided) for a,b",
- Ranks: N, Mean Rank and Sum of Ranks of each column,
- Test Statistics: Mann-Whitney U, Wilcoxon W, Z, Asymp. Sig., and Exact Sig. when it applies.
How to read the result
Each group must be its own column. If the scores are in one column and the group (gender, class) in another, first split them with STATS_SPLIT_COLS — one column per group — and select those columns here.
Start with the p (Asymp. Sig., or Exact Sig. when it is shown): below 0.05 — one group tends to have higher values.
The Ranks table shows which one: the group with the higher Mean Rank; the sign of Z says the same (positive — the first column is higher).
Use it instead of the independent t test for ranks, rating scales, skewed data or small groups.
In a report: "Scores were higher in group A (mean rank 60.1) than in group B (40.9), U = 770, Z = 3.31, p = .001."
What each number means
Ranks
Column— ColumnRead the numbers along the row for that column.
N— NCompare it with your sample: a small group makes the test weak.
Mean Rank— Mean rankThe rank-test counterpart of the mean: the group with the higher mean rank tends to have the higher values. Report it next to the test, or the medians of the groups.
Sum of Ranks— Sum of ranksAn intermediate number: the test statistic is computed from it.
Test Statistics
Mann-Whitney U— Mann–Whitney USmall U — one group tends to lie below the other; n₁·n₂/2 — the groups are mixed evenly. In a report: U = 1175.5, Z = 0.52, p = .600.
Wilcoxon W— Wilcoxon WThe same test as U written another way; U is the one usually reported.
Z— z statisticA step on the way to p: beyond about ±1.96 a two-sided test is significant at 0.05.
Asymp. Sig. (2-tailed)— Asymptotic significanceThis is the p of the test. Below 0.05 — one group tends to have higher values than the other. In a report: U = 1175.5, Z = 0.52, p = .600.
How it is computed
The first two selected columns are the two groups, each with its own valid values.
All values are ranked together (ties get the average rank); U₁ = R₁ − n₁(n₁ + 1)/2 and the report shows the smaller U, and W — the rank sum of that group, as SPSS NPAR TESTS.
Z is the normal approximation with the tie correction and no continuity correction; p from the normal distribution, 2- or 1-tailed by alternative.
For small groups without ties the exact p (Dineen and Blakesley) is added, as SPSS.
Errors
One cell instead of the report:
- one column: "Mann-Whitney U Test requires at least 2 groups";
- fewer than 2 values in a column: "Mann-Whitney U Test: need at least 2 observations";
- every value in both columns equal: "Mann-Whitney U Test: all values in a and b are equal, the test is not defined";
- a text column without value labels: "Mann-Whitney U Test needs numeric columns, text columns: t (add value labels or recode to numbers)";
- a misspelled alternative: 'alternative must be two-sided, greater or less (or 1, -1), got "grater"';
- a column name that does not exist: "Column nope does not exist".
About STATS_MANN_WHITNEY
STATS_MANN_WHITNEY compares two independent groups by ranks. It replaces the independent t test when the data are not normal, are rating scales (1–5) or ranks, or have outliers. The first two selected columns are the two groups. If the scores are in one column and the group in another, split them first with STATS_SPLIT_COLS. The report spills below the formula cell and recalculates by itself when new responses arrive from Google Forms.
All values are ranked together. The Ranks table shows the Mean Rank of each group: the group with the higher mean rank tends to have higher values. U, W and Z follow the definitions of SPSS: U is the smaller of the two U values, Wilcoxon W is the rank sum of that group, and Z is corrected for ties, without the continuity correction. Asymp. Sig. is the p-value; for small groups without ties an Exact Sig. is added. For a one-sided test, set alternative to "greater" or "less".
Every number of the report is explained on this page in plain words, together with the line to write in your report, for example: Scores were higher in group A (mean rank 60.1) than in group B (40.9), U = 770, Z = 3.31, p = .001.