-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModule1.bas
179 lines (112 loc) · 4.33 KB
/
Module1.bas
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
Attribute VB_Name = "Module1"
Function DeriveMAD(myArray As Variant)
Dim myArray2() As Variant
Dim MAD As Double
'Get Column size
Dim Rows As Integer
Rows = Application.WorksheetFunction.Count(myArray)
'set myArray2 to 1 to # of Rows
ReDim myArray2(1 To Rows)
'Derive distance from Median
Dim i As Integer
For i = 1 To Rows
myArray2(i) = Abs(myArray(i) - Application.WorksheetFunction.Median(myArray))
Next i
MAD = Application.WorksheetFunction.Median(myArray2)
DeriveMAD = MAD
End Function
Function DeriveMADZPct(value As Double, myArray As Variant)
Dim myArray3() As Variant
Dim MAD As Double
MAD = DeriveMAD(myArray)
Dim Rows As Integer
Dim theMedian As Double
Rows = Application.WorksheetFunction.Count(myArray)
'set myArray2 to 1 to # of Rows
ReDim myArray3(1 To Rows)
Dim i As Integer
For i = 1 To Rows
myArray3(i) = (myArray(i) - Application.WorksheetFunction.Median(myArray)) / MAD
Next i
value = (value - Application.WorksheetFunction.Median(myArray)) / MAD
If (Abs(value) <= 1) Then
DeriveMADZPct = ((value + 1) / 4) + 0.25
ElseIf (value > 1) Then
DeriveMADZPct = ((value - 1) / (Application.WorksheetFunction.Max(myArray3) - 1)) * 0.25 + 0.75
ElseIf (value < -1) Then
DeriveMADZPct = 0.25 - ((value + 1) / (Application.WorksheetFunction.Min(myArray3) + 1) * 0.25)
ElseIf value = 0 Then
DeriveMADZPct = 0.5
End If
End Function
Function returnColumns(myArray As Range)
Dim i As Integer
i = myArray.Columns.Count
returnColumns = i
End Function
Function ReturnArray(myArray As Range)
Dim myArray4() As Variant
Dim Rows As Integer
Dim Columns As Integer
Rows = Application.WorksheetFunction.Count(myArray)
Columns = returnColumns(myArray)
'set myArray4 to 1 to # of Rows
ReDim myArray4(1 To Columns, 1 To Rows)
myArray4 = myArray
ReturnArray = myArray4()
End Function
'Returns array as Percents based on MAD Z Score normalization around 1 MAD.
Function DeriveMADZPercents(myArray As Range)
Dim myArray4() As Variant
Dim MAD As Double
Dim MaxZ As Double
Dim MinZ As Double
MAD = DeriveMAD(myArray)
Dim Rows As Integer
Dim Columns As Integer
Dim theMedian As Double
theMedian = Application.WorksheetFunction.Median(myArray)
Rows = Application.WorksheetFunction.Count(myArray)
Columns = returnColumns(myArray)
'Destination array. Set myArray4 to 1 to # of Rows
ReDim myArray4(1 To Columns, 1 To Rows)
Dim h As Integer
For h = 1 To Columns
Dim i As Integer
'Assign Z's first, derive max/min z's
For i = 1 To Rows
value = myArray(h, i)
'value = (value - Application.WorksheetFunction.Median(myArray)) / MAD
value = (value - theMedian) / MAD
myArray4(h, i) = value
If (i = 1) Then
MinZ = value
MaxZ = value
End If
'max/min z's
If (value > MaxZ) Then
MaxZ = value
End If
If (value < MinZ) Then
MinZ = value
End If
Next i
'necessary to have max and minz derived per column ahead of time.
For i = 1 To Rows
value = myArray4(h, i)
If (Abs(value) <= 1) Then
value = ((value + 1) / 4) + 0.25
ElseIf (value > 1) Then
value = (value - 1) / (MaxZ - 1) * 0.25 + 0.75
'(value - 1) '/ (Application.WorksheetFunction.Max(myArray3) - 1) '* 0.25 + 0.75
ElseIf (value < -1) Then
value = 0.25 - ((value + 1) / (MinZ + 1) * 0.25)
ElseIf value = 0 Then
value = 0.5
End If
myArray4(h, i) = value
Next i
Next h
'Assign %'s second (need Z's to derive Max's/Min's)
DeriveMADZPercents = Application.WorksheetFunction.Transpose(myArray4())
End Function