Skip to content

Commit 6570bf4

Browse files
feat(stats/mannwhitneyu): add Mann–Whitney U test package
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: passed - task: lint_package_json status: passed - task: lint_repl_help status: passed - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: passed - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: passed - task: lint_python status: na - task: lint_r status: passed - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: passed - task: lint_license_headers status: passed ---
1 parent e924862 commit 6570bf4

21 files changed

Lines changed: 1899 additions & 6 deletions

File tree

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2018 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Mann-Whitney U Test
22+
23+
> Nonparametric hypothesis test comparing two independent samples.
24+
25+
<section class="usage">
26+
27+
## Usage
28+
29+
```javascript
30+
var mannWhitneyU = require( '@stdlib/stats/mannwhitneyu' );
31+
```
32+
33+
#### mannWhitneyU( x, y\[, options] )
34+
35+
Given two independent samples x and y, the function computes the Mann–Whitney U rank-sum test to assess whether the distributions differ.
36+
37+
```javascript
38+
var out = mannWhitneyU( [ 7, 8, 9 ], [ 1, 2, 3 ] );
39+
/* returns
40+
{
41+
'U': 0,
42+
'pValue': 0.025,
43+
'rejected': true
44+
}
45+
*/
46+
47+
out = mannWhitneyU( [ 10, 11, 10, 12 ], [ 9, 11, 10, 10 ] );
48+
/* returns
49+
{
50+
'U': 4.5,
51+
'pValue': 0.312,
52+
'rejected': false
53+
}
54+
*/
55+
```
56+
57+
<!-- run-disable -->
58+
59+
The function accepts the following `options`:
60+
61+
- **alpha**: `number` in the interval `[0,1]` giving the significance level of the hypothesis test. Default: `0.05`.
62+
- **alternative**: Either `two-sided`, `less` or `greater`. Indicates the direction of the hypothesis test. `'greater'` tests whether values in `x` tend to be larger than those in `y`, `'less'` tests whether values in `x` tend to be smaller than those in `y`, and `'two-sided'` tests for any difference in distributions.
63+
64+
By default, the hypothesis test is carried out at a significance level of `0.05`. To choose a different significance level, set the `alpha` option.
65+
66+
```javascript
67+
var out = mannWhitneyU( [ 7, 8, 9 ], [ 1, 2, 3 ], {
68+
'alpha': 0.05,
69+
'alternative': 'greater'
70+
});
71+
/* returns
72+
{
73+
'U': 0,
74+
'pValue': 0.025,
75+
'rejected': true
76+
}
77+
*/
78+
```
79+
80+
By default, a two-sided test is performed. To perform either of the one-sided tests, set the `alternative` option to `less` or `greater`.
81+
82+
```javascript
83+
out = mannWhitneyU( [ 5, 6, 7, 8 ], [ 1, 2, 3, 4 ], {
84+
'alternative': 'greater',
85+
'alpha': 0.05
86+
});
87+
/* returns
88+
{
89+
'U': 0,
90+
'pValue': 0.0104,
91+
'rejected': true
92+
}
93+
*/
94+
95+
out = mannWhitneyU( [ 5, 6, 7, 8 ], [ 1, 2, 3, 4 ], {
96+
'alternative': 'less',
97+
'alpha': 0.05
98+
});
99+
/* returns
100+
{
101+
'U': 0,
102+
'pValue': 0.9896,
103+
'rejected': false
104+
}
105+
*/
106+
```
107+
108+
</section>
109+
110+
<!-- /.usage -->
111+
112+
<section class="examples">
113+
114+
## Examples
115+
116+
<!-- eslint no-undef: "error" -->
117+
118+
```javascript
119+
var mannWhitneyU = require( '@stdlib/stats/mannwhitneyu' );
120+
121+
var x = [ 12, 15, 14, 10, 13 ];
122+
var y = [ 7, 9, 6, 8, 7 ];
123+
124+
var out = mannWhitneyU( x, y );
125+
/* returns
126+
{
127+
'U': 0,
128+
'pValue': 0.009,
129+
'rejected': true
130+
}
131+
*/
132+
133+
out = mannWhitneyU( [ 5, 6, 7, 8 ], [ 1, 2, 3, 4 ] );
134+
/* returns
135+
{
136+
'U': 0,
137+
'pValue': 0.0208,
138+
'rejected': true
139+
}
140+
*/
141+
142+
out = mannWhitneyU( [ 5, 6, 7, 8 ], [ 1, 2, 3, 4 ], {
143+
'alternative': 'greater'
144+
});
145+
/* returns
146+
{
147+
'U': 0,
148+
'pValue': 0.0104,
149+
'rejected': true
150+
}
151+
*/
152+
153+
out = mannWhitneyU( [ 1, 2, 2, 3 ], [ 2, 3, 4, 5 ], {
154+
'alternative': 'greater',
155+
'alpha': 0.05
156+
});
157+
/* returns
158+
{
159+
'U': 2.5,
160+
'pValue': 0.057,
161+
'rejected': false
162+
}
163+
*/
164+
```
165+
166+
</section>
167+
168+
<!-- /.examples -->
169+
170+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
171+
172+
<section class="related">
173+
174+
</section>
175+
176+
<!-- /.related -->
177+
178+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
179+
180+
<section class="links">
181+
182+
</section>
183+
184+
<!-- /.links -->
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2018 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var bench = require( '@stdlib/bench' );
24+
var isObject = require( '@stdlib/assert/is-object' );
25+
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
26+
var discreteUniform = require( '@stdlib/random/base/discrete-uniform' );
27+
var pkg = require( './../package.json' ).name;
28+
var mannWhitneyU = require( './../lib' );
29+
30+
31+
// MAIN //
32+
33+
bench( pkg, function benchmark( b ) {
34+
var result;
35+
var x;
36+
var y;
37+
var i;
38+
39+
x = [];
40+
y = [];
41+
for ( i = 0; i < 100; i++ ) {
42+
x.push( 0 );
43+
y.push( 0 );
44+
}
45+
46+
b.tic();
47+
for ( i = 0; i < b.iterations; i++ ) {
48+
fillArray( x );
49+
fillArray( y );
50+
result = mannWhitneyU( x, y );
51+
if ( typeof result !== 'object' ) {
52+
b.fail( 'should return an object' );
53+
}
54+
}
55+
b.toc();
56+
if ( !isObject( result ) ) {
57+
b.fail( 'should return an object' );
58+
}
59+
b.pass( 'benchmark finished' );
60+
b.end();
61+
});
62+
63+
bench( pkg+'::one-sided', function benchmark( b ) {
64+
var result;
65+
var opts;
66+
var x;
67+
var y;
68+
var i;
69+
70+
opts = {
71+
'alternative': 'greater'
72+
};
73+
x = [];
74+
y = [];
75+
for ( i = 0; i < 100; i++ ) {
76+
x.push( 0 );
77+
y.push( 0 );
78+
}
79+
80+
b.tic();
81+
for ( i = 0; i < b.iterations; i++ ) {
82+
fillArray( x );
83+
fillArray( y );
84+
result = mannWhitneyU( x, y, opts );
85+
if ( typeof result !== 'object' ) {
86+
b.fail( 'should return an object' );
87+
}
88+
}
89+
b.toc();
90+
if ( !isObject( result ) ) {
91+
b.fail( 'should return an object' );
92+
}
93+
b.pass( 'benchmark finished' );
94+
b.end();
95+
});
96+
97+
bench( pkg+':print', function benchmark( b ) {
98+
var digits;
99+
var result;
100+
var output;
101+
var i;
102+
103+
result = mannWhitneyU( [ 7, 8, 9 ], [ 1, 2, 3 ] );
104+
105+
b.tic();
106+
for ( i = 0; i < b.iterations; i++ ) {
107+
digits = ( i % 8 ) + 1;
108+
output = result.print({
109+
'digits': digits
110+
});
111+
if ( typeof output !== 'string' ) {
112+
b.fail( 'should return a string' );
113+
}
114+
}
115+
b.toc();
116+
if ( !isString( output ) ) {
117+
b.fail( 'should return a string' );
118+
}
119+
b.pass( 'benchmark finished' );
120+
b.end();
121+
});
122+
123+
124+
// FUNCTIONS //
125+
126+
function fillArray( arr ) {
127+
var i;
128+
for ( i = 0; i < arr.length; i++ ) {
129+
arr[ i ] = discreteUniform( 0, 100 );
130+
}
131+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{{alias}}( x, y[, options] )
2+
Computes the Mann–Whitney U rank-sum test for the difference between two
3+
independent samples.
4+
5+
The returned object comes with a `.print()` method which when invoked will
6+
print a formatted output of the results of the hypothesis test.
7+
8+
Parameters
9+
----------
10+
x: Array<number>
11+
First independent sample.
12+
13+
y: Array<number>
14+
Second independent sample.
15+
16+
options: Object (optional)
17+
Options.
18+
19+
options.alpha: number (optional)
20+
Number in the interval `[0,1]` giving the significance level of the
21+
hypothesis test. Default: `0.05`.
22+
23+
options.alternative: string (optional)
24+
Indicates whether the alternative hypothesis is that the distribution of
25+
`x` is shifted to the right of `y` (`greater`), to the left of `y`
26+
(`less`) or that they differ (`two-sided`). Default: `'two-sided'`.
27+
28+
Returns
29+
-------
30+
out: Object
31+
Test result object.
32+
33+
out.alpha: number
34+
Used significance level.
35+
36+
out.rejected: boolean
37+
Test decision.
38+
39+
out.pValue: number
40+
p-value of the test.
41+
42+
out.U: number
43+
Mann–Whitney U statistic.
44+
45+
out.U1: number
46+
U value for sample `x`.
47+
48+
out.U2: number
49+
U value for sample `y`.
50+
51+
out.alternative: string
52+
Alternative hypothesis (`two-sided`, `less` or `greater`).
53+
54+
out.method: string
55+
Name of the test.
56+
57+
out.print: Function
58+
Function to print formatted output.
59+
60+
Examples
61+
--------
62+
> var out = {{alias}}( [ 7, 8, 9 ], [ 1, 2, 3 ] )
63+
{ 'U': 0, 'pValue': ~0.025, ... }
64+
65+
> out = {{alias}}( [ 5, 6, 7, 8 ], [ 1, 2, 3, 4 ], {
66+
... 'alternative': 'greater'
67+
... })
68+
{ 'U': 0, 'pValue': ~0.0104, ... }
69+
70+
> out = {{alias}}( [ 1, 2, 2, 3 ], [ 2, 3, 4, 5 ], {
71+
... 'alternative': 'greater',
72+
... 'alpha': 0.05
73+
... })
74+
{ 'U': 2.5, 'pValue': ~0.057, ... }
75+
76+
See Also
77+
--------

0 commit comments

Comments
 (0)