Skip to content

Feature Request: Support for Brunner-Munzel (next to Mann-Whitney-Wilcoxon) #346

Description

@adrianolszewski

What's the feature?

It's known that the U statistic (Mann-Whitney and the Wilcoxon version) can "run into trouble" due to unequal variances and fail to maintain the nominal significance level and power, just the same way the classic t-test. To address it, Brunner and Munzel proposed their studentised version of the MWW test the same way Welch and Satterthwaite (and Janssen - for the permutation version) proposed theirs for the Gosset's t statistic.

Both Welch-t (Lakens, 2017) and Brunner-Munzel (Karch, 2021) have been recommended for replacing their counterparts classic t and MWW in daily use.

This matters also in randomized studies. While randomization enables statistical testing under true (virtual) H0, but it does not guarantee that -in a concrete realization- the arms will be balanced in any kind of meaning, including dispersions.

Brunner-Munzel is about the same quantity as MWW - stochastic superiority (aka probabilistic index), i.e. P(B>A)+0.5*P(B=A), only accounting for unequal dispersions (probably I should rather say "scales", but I hope we can roughly stay with dispersions expressed by variances) for inference.

In R the most common implementation can be found in the brunnermunzel package.

> (tmp <- brunnermunzel::brunnermunzel.test(runif(10), rnorm(10)))

	Brunner-Munzel Test

data:  runif(10) and rnorm(10)
Brunner-Munzel Test Statistic = -0.83653, df = 10.642, p-value = 0.4212
95 percent confidence interval:
 0.06296806 0.69703194
sample estimates:
P(X<Y)+.5*P(X=Y) 
            0.38 

> str(tmp)
List of 7
 $ method   : chr "Brunner-Munzel Test"
 $ statistic: Named num -0.837
  ..- attr(*, "names")= chr "Brunner-Munzel Test Statistic"
 $ data.name: chr "runif(10) and rnorm(10)"
 $ parameter: Named num 10.6
  ..- attr(*, "names")= chr "df"
 $ estimate : Named num 0.38
  ..- attr(*, "names")= chr "P(X<Y)+.5*P(X=Y)"
 $ p.value  : num 0.421
 $ conf.int : Named num [1:2] 0.063 0.697
  ..- attr(*, "names")= chr [1:2] "lower" "upper"
  ..- attr(*, "conf.level")= num 0.95
 - attr(*, "class")= chr "htest"

Luckily, both permuted and asymptotic versions return a htest-class result, so broom::tidy() can handle it:

> broom::tidy(tmp <- brunnermunzel::brunnermunzel.test(runif(10), rnorm(10)))
# A tibble: 1 × 7
  estimate statistic p.value parameter conf.low.lower conf.high.upper method             
     <dbl>     <dbl>   <dbl>     <dbl>          <dbl>           <dbl> <chr>              
1     0.57     0.482   0.640      10.9          0.250           0.890 Brunner-Munzel Test

> broom::tidy(tmp <- brunnermunzel::brunnermunzel.permutation.test(runif(10), rnorm(10)))
# A tibble: 1 × 3
  estimate p.value method                      
     <dbl>   <dbl> <chr>                       
1     0.32   0.237 permuted Brunner-Munzel Test

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions