Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Apply Mann-Whitney, Kruskal-Wallis, and other nonparametric methods
.claude/skills/brycewang-stanford-nonparametric-tests-guide/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 55% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 138% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 55% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 109% | 0% |
A skill for selecting and applying nonparametric statistical tests when data violate parametric assumptions. Covers rank-based tests for group comparisons, correlation, and paired data, with implementation examples and guidance on reporting.
Use nonparametric tests when:
- Data are ordinal (Likert scales, rankings)
- Distribution is clearly non-normal (heavy skew, outliers)
- Sample size is very small (n < 15-20 per group)
- Homogeneity of variance is violated
- You are analyzing ranks or medians rather than means
Use parametric tests when:
- Data are approximately normal (or n > 30 by CLT)
- Variance is homogeneous across groups
- You need greater statistical power
- The parametric assumptions are reasonably met| Parametric Test | Nonparametric Alternative | Use Case | |----------------|--------------------------|----------| | Independent t-test | Mann-Whitney U | Compare 2 independent groups | | Paired t-test | Wilcoxon signed-rank | Compare 2 related samples | | One-way ANOVA | Kruskal-Wallis H | Compare 3+ independent groups | | Repeated measures ANOVA | Friedman test | Compare 3+ related samples | | Pearson correlation | Spearman rank correlation | Measure association | | Chi-square test | Fisher's exact test | Compare proportions (small n) |
pythonfrom scipy import stats import numpy as np def mann_whitney_test(group_a: list, group_b: list) -> dict: """ Perform Mann-Whitney U test for two independent groups. Args: group_a: Observations from group A group_b: Observations from group B """ statistic, p_value = stats.mannwhitneyu( group_a, group_b, alternative="two-sided" ) n_a, n_b = len(group_a), len(group_b) # Rank-biserial correlation as effect size r = 1 - (2 * statistic) / (n_a * n_b) return { "U_statistic": statistic, "p_value": p_value, "n_a": n_a, "n_b": n_b, "median_a": np.median(group_a), "median_b": np.median(group_b), "effect_size_r": abs(r), "effect_interpretation": ( "small" if abs(r) < 0.3 else "medium" if abs(r) < 0.5 else "large" ) } # Example usage control = [12, 15, 14, 10, 13, 11, 16, 9, 14, 12] treatment = [18, 22, 19, 17, 20, 21, 16, 23, 19, 20] result = mann_whitney_test(control, treatment) print(f"U = {result['U_statistic']}, p = {result['p_value']:.4f}") print(f"Effect size r = {result['effect_size_r']:.3f} ({result['effect_interpretation']})")
pythondef kruskal_wallis_with_posthoc(*groups) -> dict: """ Perform Kruskal-Wallis test with Dunn's post-hoc comparisons. Args: *groups: Variable number of group data arrays """ # Omnibus test h_stat, p_value = stats.kruskal(*groups) result = { "H_statistic": h_stat, "p_value": p_value, "n_groups": len(groups), "group_medians": [np.median(g) for g in groups] } # If significant, perform pairwise Mann-Whitney with Bonferroni correction if p_value < 0.05: n_comparisons = len(groups) * (len(groups) - 1) // 2 pairwise = [] for i in range(len(groups)): for j in range(i + 1, len(groups)): u, p = stats.mannwhitneyu(groups[i], groups[j]) pairwise.append({ "comparison": f"Group {i+1} vs Group {j+1}", "U": u, "p_raw": p, "p_adjusted": min(p * n_comparisons, 1.0), "significant": (p * n_comparisons) < 0.05 }) result["posthoc"] = pairwise return result
pythondef wilcoxon_signed_rank(before: list, after: list) -> dict: """ Perform Wilcoxon signed-rank test for paired data. Args: before: Pre-intervention measurements after: Post-intervention measurements """ statistic, p_value = stats.wilcoxon(before, after) n = len(before) # Effect size: r = Z / sqrt(N) z_score = stats.norm.ppf(1 - p_value / 2) r = z_score / np.sqrt(n) differences = [a - b for a, b in zip(after, before)] return { "W_statistic": statistic, "p_value": p_value, "n_pairs": n, "median_difference": np.median(differences), "effect_size_r": abs(r) }
pythondef spearman_correlation(x: list, y: list) -> dict: """ Compute Spearman rank correlation. """ rho, p_value = stats.spearmanr(x, y) return { "rho": rho, "p_value": p_value, "interpretation": ( "negligible" if abs(rho) < 0.1 else "weak" if abs(rho) < 0.3 else "moderate" if abs(rho) < 0.5 else "strong" if abs(rho) < 0.7 else "very strong" ) }
Mann-Whitney U:
"A Mann-Whitney U test indicated that treatment scores
(Mdn = 20.0) were significantly higher than control scores
(Mdn = 13.0), U = 5.0, p < .001, r = .82."
Kruskal-Wallis:
"A Kruskal-Wallis H test showed a significant difference
in scores across the three conditions, H(2) = 15.32,
p < .001. Post-hoc pairwise comparisons with Bonferroni
correction revealed..."
Wilcoxon Signed-Rank:
"A Wilcoxon signed-rank test showed that the intervention
significantly improved scores (Mdn_diff = 4.5),
W = 12.0, p = .003, r = .58."
Spearman:
"There was a strong positive correlation between X and Y,
r_s = .72, p < .001."Always report effect sizes alongside p-values. For rank-biserial correlation r: small (0.1), medium (0.3), large (0.5). For Spearman rho, use standard correlation benchmarks. Effect sizes allow readers to judge practical significance independent of sample size.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 15,931 | 39,910 | +151% | 1 | 1 | 0% | 3,272 | 5,060 | +55% | 0 | 0 | — |
case-02 | fail→pass | 14,175 | 10,352 | -27% | 1 | 1 | 0% | 2,568 | 3,978 | +55% | 0 | 0 | — |
case-03 | pass→pass | 8,755 | 6,582 | -25% | 1 | 1 | 0% | 1,502 | 3,140 | +109% | 0 | 0 | — |
case-04 | pass→pass | 7,419 | 11,724 | +58% | 1 | 1 | 0% | 1,267 | 4,130 | +226% | 0 | 0 | — |
case-22 | pass→pass | 12,133 | 10,151 | -16% | 1 | 1 | 0% | 2,374 | 3,902 | +64% | 0 | 0 | — |
case-05 | pass→pass | 7,382 | 5,600 | -24% | 1 | 1 | 0% | 1,265 | 2,844 | +125% | 0 | 0 | — |
case-06 | pass→pass | 10,613 | 9,446 | -11% | 1 | 1 | 0% | 1,791 | 3,536 | +97% | 0 | 0 | — |
case-07 | fail→fail | 16,508 | 17,353 | +5% | 1 | 1 | 0% | 3,218 | 5,588 | +74% | 0 | 0 | — |
case-08 | fail→pass | 11,340 | 5,758 | -49% | 1 | 1 | 0% | 2,052 | 2,969 | +45% | 0 | 0 | — |
case-09 | pass→pass | 8,709 | 8,172 | -6% | 1 | 1 | 0% | 1,741 | 3,386 | +94% | 0 | 0 | — |
case-10 | pass→pass | 7,169 | 7,373 | +3% | 1 | 1 | 0% | 1,259 | 3,280 | +161% | 0 | 0 | — |
case-11 | pass→pass | 4,713 | 2,981 | -37% | 1 | 1 | 0% | 924 | 2,481 | +169% | 0 | 0 | — |
case-12 | pass→pass | 4,975 | 4,252 | -15% | 1 | 1 | 0% | 909 | 2,632 | +190% | 0 | 0 | — |
case-13 | fail→pass | 6,430 | 4,513 | -30% | 1 | 1 | 0% | 1,137 | 2,709 | +138% | 0 | 0 | — |
case-14 | pass→pass | 12,567 | 6,276 | -50% | 1 | 1 | 0% | 1,406 | 2,888 | +105% | 0 | 0 | — |
case-15 | pass→pass | 10,769 | 7,223 | -33% | 1 | 1 | 0% | 1,925 | 3,154 | +64% | 0 | 0 | — |
case-16 | pass→pass | 15,430 | 11,679 | -24% | 1 | 1 | 0% | 2,434 | 3,812 | +57% | 0 | 0 | — |
case-17 | pass→pass | 9,077 | 9,582 | +6% | 1 | 1 | 0% | 1,512 | 3,394 | +124% | 0 | 0 | — |
case-18 | pass→pass | 15,482 | 14,794 | -4% | 1 | 1 | 0% | 2,942 | 4,636 | +58% | 0 | 0 | — |
case-19 | pass→pass | 4,840 | 6,102 | +26% | 1 | 1 | 0% | 888 | 3,001 | +238% | 0 | 0 | — |
case-20 | pass→pass | 4,880 | 2,717 | -44% | 1 | 1 | 0% | 800 | 2,346 | +193% | 0 | 0 | — |
case-21 | pass→pass | 14,270 | 12,318 | -14% | 1 | 1 | 0% | 2,092 | 4,650 | +122% | 0 | 0 | — |
case-23 | pass→pass | 10,675 | 8,859 | -17% | 1 | 1 | 0% | 2,084 | 3,640 | +75% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.