1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package ubic.basecode.math.metaanalysis;
20
21 import ubic.basecode.math.Constants;
22 import cern.colt.list.DoubleArrayList;
23 import cern.jet.stat.Descriptive;
24 import cern.jet.stat.Probability;
25
26
27
28
29
30
31
32
33
34 public abstract class MetaAnalysis {
35
36
37
38
39
40
41
42 public static double fisherCombinePvalues( DoubleArrayList pvals ) {
43 double r = 0.0;
44 for ( int i = 0, n = pvals.size(); i < n; i++ ) {
45 r += Math.log( pvals.getQuick( i ) );
46 }
47 r *= -2.0;
48
49 return Probability.chiSquareComplemented( 2.0 * pvals.size(), r );
50 }
51
52
53
54
55
56
57
58
59
60 public double qTest( double Q, double N ) {
61
62 return Probability.chiSquareComplemented( N - 1, Q );
63 }
64
65
66
67
68
69
70
71
72
73 protected double fisherCombineLogPvalues( DoubleArrayList pvals ) {
74 double r = 0.0;
75 for ( int i = 0, n = pvals.size(); i < n; i++ ) {
76 r += pvals.getQuick( i );
77 }
78 r *= -2.0;
79
80 return Probability.chiSquareComplemented( 2.0 * pvals.size(), r );
81 }
82
83
84
85
86
87
88
89 protected DoubleArrayList metaFEWeights( DoubleArrayList variances ) {
90 DoubleArrayList w = new DoubleArrayList( variances.size() );
91
92 for ( int i = 0; i < variances.size(); i++ ) {
93 double v = variances.getQuick( i );
94 if ( v <= Constants.SMALL ) {
95 v = Constants.SMALL;
96 System.err.println( "Tiny variance " + v );
97 }
98 w.add( 1 / v );
99 }
100
101 return w;
102 }
103
104
105
106
107
108
109
110 protected double metaRESampleVariance( DoubleArrayList effectSizes ) {
111 return Descriptive.sampleVariance( effectSizes, Descriptive.mean( effectSizes ) );
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 protected double metaREVariance( DoubleArrayList effectSizes, DoubleArrayList variances, DoubleArrayList weights ) {
146
147 if ( !( effectSizes.size() == weights.size() && weights.size() == variances.size() ) )
148 throw new IllegalArgumentException( "Unequal sizes" );
149
150
151 double q = qStatistic( effectSizes, variances, weightedMean( effectSizes, weights ) );
152
153 double c = Descriptive.sum( weights ) - Descriptive.sumOfSquares( weights ) / Descriptive.sum( weights );
154 return Math.max( ( q - ( effectSizes.size() - 1 ) ) / c, 0.0 );
155 }
156
157
158
159
160
161
162
163
164
165
166
167
168
169 protected DoubleArrayList metaREWeights( DoubleArrayList variances, double sampleVariance ) {
170 DoubleArrayList w = new DoubleArrayList( variances.size() );
171
172 for ( int i = 0; i < variances.size(); i++ ) {
173 if ( variances.getQuick( i ) <= 0 ) {
174 throw new IllegalStateException( "Negative or zero variance" );
175 }
176 w.add( 1 / ( variances.getQuick( i ) + sampleVariance ) );
177 }
178
179 return w;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193 protected double metaVariance( DoubleArrayList variances ) {
194 double var = 0.0;
195 for ( int i = 0; i < variances.size(); i++ ) {
196 var += 1.0 / variances.getQuick( i );
197 }
198 if ( var == 0.0 ) {
199 var = Double.MIN_VALUE;
200
201 }
202 return 1.0 / var;
203 }
204
205
206
207
208
209
210
211
212
213
214
215 protected double metaVariance( DoubleArrayList weights, DoubleArrayList qualityIndices ) {
216 double num = 0.0;
217 double denom = 0.0;
218 for ( int i = 0; i < weights.size(); i++ ) {
219 num += Math.pow( weights.getQuick( i ), 2 ) * qualityIndices.getQuick( i );
220 denom += Math.pow( weights.getQuick( i ) * qualityIndices.getQuick( i ), 2 );
221 }
222 if ( denom == 0.0 ) {
223 throw new IllegalStateException( "Attempt to divide by zero." );
224 }
225 return num / denom;
226 }
227
228
229
230
231
232
233
234
235 protected double metaZscore( double metaEffectSize, double metaVariance ) {
236 return Math.abs( metaEffectSize ) / Math.sqrt( metaVariance );
237 }
238
239
240
241
242
243
244
245
246
247 protected double qStatistic( DoubleArrayList effectSizes, DoubleArrayList variances, double globalMean ) {
248
249 if ( !( effectSizes.size() == variances.size() ) ) throw new IllegalArgumentException( "Unequal sizes" );
250
251 double r = 0.0;
252 for ( int i = 0, n = effectSizes.size(); i < n; i++ ) {
253 r += Math.pow( effectSizes.getQuick( i ) - globalMean, 2.0 ) / variances.getQuick( i );
254 }
255 return r;
256 }
257
258
259
260
261
262
263
264
265
266
267
268 protected double weightedMean( DoubleArrayList effectSizes, DoubleArrayList weights ) {
269
270 if ( !( effectSizes.size() == weights.size() ) ) throw new IllegalArgumentException( "Unequal sizes" );
271
272 double wm = 0.0;
273 for ( int i = 0; i < effectSizes.size(); i++ ) {
274 wm += weights.getQuick( i ) * effectSizes.getQuick( i );
275 }
276
277 double s = Descriptive.sum( weights );
278
279 if ( s == 0.0 ) return 0.0;
280 return wm /= s;
281 }
282
283
284
285
286
287
288
289
290
291
292 protected double weightedMean( DoubleArrayList effectSizes, DoubleArrayList weights, DoubleArrayList qualityIndices ) {
293
294 if ( !( effectSizes.size() == weights.size() && weights.size() == qualityIndices.size() ) )
295 throw new IllegalArgumentException( "Unequal sizes" );
296
297 double wm = 0.0;
298 for ( int i = 0; i < effectSizes.size(); i++ ) {
299 wm += weights.getQuick( i ) * effectSizes.getQuick( i ) * qualityIndices.getQuick( i );
300 }
301 return wm /= Descriptive.sum( weights ) * Descriptive.sum( qualityIndices );
302 }
303 }