-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbchTerts.js
116 lines (80 loc) · 3.59 KB
/
bchTerts.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
// Bivariate choropleth tertiles
//------------------------------------------------------------------------------
// Authors: Corey Devin Anderson and Kirankumar Batchu
// The function bchTerts() takes two input arrays and bins values for each array
// into one of three classes ('L', 'M', 'H') based on tercile boundaries, and then
// concatenates them into a single array of two-letter categories, with nine possible
// states ('LL','LM', 'LH', 'ML', 'MM', 'MH', 'HL', 'HM', or 'HH') to support a 3 x 3
// color scheme in a bivariate choropleth map.
// Use bchTerts2() if your data contain null values.
// Dependencies:
// Dependencies:
// simple-statistics (for quantile function: ss.quantile()) was used to determine
// array values associated with the tertiles; see script tag in HTML pane for
// src information for simple-statistics.
//------------------------------------------------------------------------------
// Helper functions:
// getTerts(your_array):
// Takes a single array and returns an array of length 4 containing the break points
// that define the tertiles (including 0 and 1).
// lmh(value, your_terts)
// Given the breaks from getTerts(), classify each member of the array as
// "L", "M", or "H".
//
// As written lmh() maps each value in the input array to its respective
// category ('L', 'M', or 'H') in an output array using an anonymous function
// with a nested call to get_terts().
//------------------------------------------------------------------------------
// get_terts()
function getTerts(yourArray) {
const tertInts = [0, 1, 2, 3]
const terts = math.divide(tertInts, 3)
let out = terts.map((x) => ss.quantile(yourArray, x))
return(out)
}
// Test?
// console.log(getTerts(EPL_AGE65))
//------------------------------------------------------------------------------
// lmh()
// This function returns the tertiles T1, T2, and T3 as 'L', 'M', and 'H'.
// Use second solution (V2) below.
// The first solution (V1) uses an indexed for loop with an if{}else if{} statement to class
// components (as "L", "M", or "H")
// The second solution (V2) uses only the if{}/else if{} statement and is intended to be used in
// an anonymous function with .map()
// Both get_terts() and lmh() are used as helper functions in bch(), where the call to get_terts()
// can be passed directly in the call to lmh().
// V1
// function lmh(your_array, your_terts) {
// label_array = math.zeros(array_length)
// for (j = 0; j < array_length; j++) {
// if (your_array[j] <= your_terts["_data"][1]) {
// label_array["_data"][j] = "L"
// } else if (your_array[j] > your_terts["_data"][1] && your_array[j] <= your_terts["_data"][2]) {
// label_array["_data"][j] = "M"
// } else if (your_array[j] > your_terts["_data"][2] && your_array[j] <= your_terts["_data"][3]) {
// label_array["_data"][j] = "H"
// }
// }
// return(label_array)
// }
// V2: use this!
function lmh(value, yourTerts) {
if (value <= yourTerts[1]) {
return "L";
} else if (value > yourTerts[1] && value <= yourTerts[2]) {
return "M";
} else if (value > yourTerts[2] && value <= yourTerts[3]) {
return "H";
}
}
//------------------------------------------------------------------------------
// bchTerts()
function bchTerts(array1, array2) {
let a = array1.map((x) => lmh(x, getTerts(array1)));
let b = array2.map((x) => lmh(x, getTerts(array2)));
let c = a.map((x, i) => x + String(b[i]));
return c;
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------