/
quantile-test.js
126 lines (111 loc) · 5.16 KB
/
quantile-test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import assert from "assert";
import {quantile, quantileIndex, quantileSorted} from "../src/index.js";
it("quantileSorted(array, p) requires sorted numeric input, quantile doesn't", () => {
assert.strictEqual(quantileSorted([1, 2, 3, 4], 0), 1);
assert.strictEqual(quantileSorted([1, 2, 3, 4], 1), 4);
assert.strictEqual(quantileSorted([4, 3, 2, 1], 0), 4);
assert.strictEqual(quantileSorted([4, 3, 2, 1], 1), 1);
assert.strictEqual(quantile([1, 2, 3, 4], 0), 1);
assert.strictEqual(quantile([1, 2, 3, 4], 1), 4);
assert.strictEqual(quantile([4, 3, 2, 1], 0), 1);
assert.strictEqual(quantile([4, 3, 2, 1], 1), 4);
});
it("quantile() accepts an iterable", () => {
assert.strictEqual(quantile(new Set([1, 2, 3, 4]), 1), 4);
});
it("quantile(array, p) uses the R-7 method", () => {
const even = [3, 6, 7, 8, 8, 10, 13, 15, 16, 20];
assert.strictEqual(quantile(even, 0), 3);
assert.strictEqual(quantile(even, 0.25), 7.25);
assert.strictEqual(quantile(even, 0.5), 9);
assert.strictEqual(quantile(even, 0.75), 14.5);
assert.strictEqual(quantile(even, 1), 20);
const odd = [3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20];
assert.strictEqual(quantile(odd, 0), 3);
assert.strictEqual(quantile(odd, 0.25), 7.5);
assert.strictEqual(quantile(odd, 0.5), 9);
assert.strictEqual(quantile(odd, 0.75), 14);
assert.strictEqual(quantile(odd, 1), 20);
});
it("quantile(array, p) coerces values to numbers", () => {
const strings = ["1", "2", "3", "4"];
assert.strictEqual(quantile(strings, 1 / 3), 2);
assert.strictEqual(quantile(strings, 1 / 2), 2.5);
assert.strictEqual(quantile(strings, 2 / 3), 3);
const dates = [new Date(Date.UTC(2011, 0, 1)), new Date(Date.UTC(2012, 0, 1))];
assert.strictEqual(quantile(dates, 0), +new Date(Date.UTC(2011, 0, 1)));
assert.strictEqual(quantile(dates, 1 / 2), +new Date(Date.UTC(2011, 6, 2, 12)));
assert.strictEqual(quantile(dates, 1), +new Date(Date.UTC(2012, 0, 1)));
});
it("quantile(array, p) returns an exact value for integer p-values", () => {
const data = [1, 2, 3, 4];
assert.strictEqual(quantile(data, 1 / 3), 2);
assert.strictEqual(quantile(data, 2 / 3), 3);
});
it("quantile(array, p) returns the expected value for integer or fractional p", () => {
const data = [3, 1, 2, 4, 0];
assert.strictEqual(quantile(data, 0 / 4), 0);
assert.strictEqual(quantile(data, 0.1 / 4), 0.1);
assert.strictEqual(quantile(data, 1 / 4), 1);
assert.strictEqual(quantile(data, 1.5 / 4), 1.5);
assert.strictEqual(quantile(data, 2 / 4), 2);
assert.strictEqual(quantile(data, 2.5 / 4), 2.5);
assert.strictEqual(quantile(data, 3 / 4), 3);
assert.strictEqual(quantile(data, 3.2 / 4), 3.2);
assert.strictEqual(quantile(data, 4 / 4), 4);
});
it("quantile(array, p) returns the first value for p = 0", () => {
const data = [1, 2, 3, 4];
assert.strictEqual(quantile(data, 0), 1);
});
it("quantile(array, p) returns the last value for p = 1", () => {
const data = [1, 2, 3, 4];
assert.strictEqual(quantile(data, 1), 4);
});
it("quantile(array, p) returns undefined if p is not a number", () => {
assert.strictEqual(quantile([1, 2, 3]), undefined);
assert.strictEqual(quantile([1, 2, 3], "no"), undefined);
assert.strictEqual(quantile([1, 2, 3], NaN), undefined);
assert.strictEqual(quantile([1, 2, 3], null), 1); // +null is 0
});
it("quantile(array, p, f) observes the specified accessor", () => {
assert.strictEqual(quantile([1, 2, 3, 4].map(box), 0.5, unbox), 2.5);
assert.strictEqual(quantile([1, 2, 3, 4].map(box), 0, unbox), 1);
assert.strictEqual(quantile([1, 2, 3, 4].map(box), 1, unbox), 4);
assert.strictEqual(quantile([2].map(box), 0, unbox), 2);
assert.strictEqual(quantile([2].map(box), 0.5, unbox), 2);
assert.strictEqual(quantile([2].map(box), 1, unbox), 2);
assert.strictEqual(quantile([], 0, unbox), undefined);
assert.strictEqual(quantile([], 0.5, unbox), undefined);
assert.strictEqual(quantile([], 1, unbox), undefined);
});
it("quantileIndex(array, p) returns the index", () => {
assert.deepStrictEqual(quantileIndex([1, 2], 0.2), 0);
assert.deepStrictEqual(quantileIndex([1, 2, 3], 0.2), 0);
assert.deepStrictEqual(quantileIndex([1, 3, 2], 0.2), 0);
assert.deepStrictEqual(quantileIndex([2, 3, 1], 0.2), 2);
assert.deepStrictEqual(quantileIndex([1], 0.2), 0);
assert.deepStrictEqual(quantileIndex([], 0.2), undefined);
});
it("quantileIndex(array, 0) returns the minimum index", () => {
assert.deepStrictEqual(quantileIndex([1, 2], 0), 0);
assert.deepStrictEqual(quantileIndex([1, 2, 3], 0), 0);
assert.deepStrictEqual(quantileIndex([1, 3, 2], 0), 0);
assert.deepStrictEqual(quantileIndex([2, 3, 1], 0), 2);
assert.deepStrictEqual(quantileIndex([1], 0), 0);
assert.deepStrictEqual(quantileIndex([], 0), undefined);
});
it("quantileIndex(array, 1) returns the maxium index", () => {
assert.deepStrictEqual(quantileIndex([1, 2], 1), 1);
assert.deepStrictEqual(quantileIndex([1, 2, 3], 1), 2);
assert.deepStrictEqual(quantileIndex([1, 3, 2], 1), 1);
assert.deepStrictEqual(quantileIndex([2, 3, 1], 1), 1);
assert.deepStrictEqual(quantileIndex([1], 1), 0);
assert.deepStrictEqual(quantileIndex([], 1), undefined);
});
function box(value) {
return {value: value};
}
function unbox(box) {
return box.value;
}