Clover coverage report - baseCode - 0.2.5 Coverage timestamp: Tue Apr 12 2005 11:31:58 EDT FRAMES NO FRAMES |
file stats: | LOC: | 241 |  | Methods: | 16
| NCLOC: | 122 |  | Classes: | 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
Source file | Conditionals | Statements | Methods | TOTAL
CorrelationEffectMetaAnalysis.java | 75% | 84.8% | 68.8% | 80% |

1 |  |
     package baseCode.math.metaanalysis;
2 |  |
3 |  |
     import baseCode.math.CorrelationStats;
4 |  |
     import cern.colt.list.DoubleArrayList;
5 |  |
     import cern.jet.stat.Descriptive;
6 |  |
     import cern.jet.stat.Probability;
7 |  |
8 |  |
     /**
9 |  |
      * Implementation of meta-analysis of correlations along the lines of chapter 18 of Cooper and Hedges, "Handbook of
10 |  |
      * Research Synthesis". Both fixed and random effects models are supported, with z-transformed or untransformed
11 |  |
      * correlations.
12 |  |
      * <hr>
13 |  |
      * <p>
14 |  |
      * Copyright (c) 2004 Columbia University
15 |  |
      *
16 |  |
      * @author pavlidis
17 |  |
      * @version $Id: CorrelationEffectMetaAnalysis.java,v 1.8 2005/03/21 18:01:03 pavlidis Exp $
18 |  |
      */
19 |  |
     public class CorrelationEffectMetaAnalysis extends MetaAnalysis {
20 |  |
21 |  |
        private boolean transform = false;
22 |  |
        private boolean fixed = true;
23 |  |
24 |  |
        private double z; // z score
25 |  |
        private double p; // probability
26 |  |
        private double q; // q-score;
27 |  |
        private double e; // unconditional effect;
28 |  |
        private double v; // unconditional variance;
29 |  |
        private double n; // total sample size
30 |  |
        private double bsv; // between-studies variance component;
31 |  |
32 | 36 |
        public CorrelationEffectMetaAnalysis( boolean fixed, boolean transform ) {
33 | 36 |
           this.fixed = fixed;
34 | 36 |
           this.transform = transform;
35 |  |
        }
36 |  |
37 | 0 |
        public CorrelationEffectMetaAnalysis() {
38 |  |
        }
39 |  |
40 |  |
        /**
41 |  |
         * Following CH section 2.2.
42 |  |
         * <p>
43 |  |
         * There are four possible cases (for now):
44 |  |
         * <ol>
45 |  |
         * <li>Fixed effects, Z-transformed. Weights are computed using CH eqns 18-8 and 18-3
46 |  |
         * <li>Fixed effects, untransformed. Weights are computed using CH eqns 18-10 and 18-3
47 |  |
         * <li>Random effects, Z-transformed. Weights are computed using CH eqns 18-20, 18-8 with 18-3
48 |  |
         * <li>Random effects, untransformed. Weights are computed using CH eqns 18-10, 18-20, 18-24.
49 |  |
         * </ol>
50 |  |
         * The default is untransformed, fixed effects.
51 |  |
         *
52 |  |
         * @param correlations - NOT fisher transformed. This routine takes care of that.
53 |  |
         * @param sampleSizes
54 |  |
         * @return p-value. The p-value is also stored in the field p.
55 |  |
         */
56 | 9 |
        public double run( DoubleArrayList effects, DoubleArrayList sampleSizes ) {
57 |  |
58 | 9 |
           DoubleArrayList weights;
59 | 9 |
           DoubleArrayList conditionalVariances;
60 | 9 |
           this.n = Descriptive.sum( sampleSizes );
61 |  |
62 | 9 |
           if ( transform ) {
63 | 5 |
              DoubleArrayList fzte = CorrelationStats.fisherTransform( effects );
64 |  |
65 |  |
              // initial values.
66 | 5 |
              conditionalVariances = fisherTransformedSamplingVariances( sampleSizes );
67 | 5 |
              weights = metaFEWeights( conditionalVariances );
68 | 5 |
              this.q = super.qStatistic( fzte, conditionalVariances, super.weightedMean( fzte, weights ) );
69 |  |
70 | 5 |
              if ( !fixed ) { // adjust the conditional variances and weights.
71 | 2 |
                 this.bsv = metaREVariance( fzte, conditionalVariances, weights );
72 |  |
73 | 2 |
                 for ( int i = 0; i < conditionalVariances.size(); i++ ) {
74 | 40 |
                    conditionalVariances.setQuick( i, conditionalVariances.getQuick( i ) + bsv );
75 |  |
                 }
76 | 2 |
                 weights = metaFEWeights( conditionalVariances );
77 |  |
              }
78 |  |
79 | 5 |
              this.e = super.weightedMean( fzte, weights );
80 |  |
           } else {
81 |  |
82 | 4 |
              conditionalVariances = samplingVariances( effects, sampleSizes );
83 | 4 |
              weights = metaFEWeights( conditionalVariances );
84 | 4 |
              this.q = super.qStatistic( effects, conditionalVariances, super.weightedMean( effects, weights ) );
85 |  |
86 | 4 |
              if ( !fixed ) { // adjust the conditional variances and weights.
87 | 1 |
                 this.bsv = metaREVariance( effects, conditionalVariances, weights );
88 | 1 |
                 for ( int i = 0; i < conditionalVariances.size(); i++ ) {
89 | 20 |
                    conditionalVariances.setQuick( i, conditionalVariances.getQuick( i ) + bsv );
90 |  |
                 }
91 |  |
92 | 1 |
                 weights = metaFEWeights( conditionalVariances );
93 |  |
              }
94 |  |
95 | 4 |
              this.e = super.weightedMean( effects, weights );
96 |  |
           }
97 | 9 |
           this.v = super.metaVariance( conditionalVariances );
98 | 9 |
           this.z = Math.abs( e ) / Math.sqrt( v );
99 | 9 |
           this.p = Probability.errorFunctionComplemented( z );
100 |  |
101 |  |
           // System.err.println(effects);
102 |  |
103 |  |
           //      if ( qTest( q, effects.size() ) < 0.05 ) {
104 |  |
           //         System.err.println("Q was significant: " + qTest( q, effects.size() ) );
105 |  |
           //      }
106 |  |
107 | 9 |
           return p;
108 |  |
        }
109 |  |
110 |  |
        /**
111 |  |
         * Equation 18-10 from CH. For untransformed correlations.
112 |  |
         * <p>
113 |  |
         *
114 |  |
         * <pre>
115 |  |
         * v_i = ( 1 - r_i &circ; 2 ) &circ; 2 / ( n_i - 1 )
116 |  |
         * </pre>
117 |  |
         *
118 |  |
         * <p>
119 |  |
         * I added a regularization to this, so that we don't get ridiculous variances when correlations are close to 1 (this
120 |  |
         * happens). If the correlation is very close to 1 (or -1), we fudge it to be a value less close to 1 (e.g., 0.999)
121 |  |
         * </p>
122 |  |
         *
123 |  |
         * @param r
124 |  |
         * @param n
125 |  |
         * @return
126 |  |
         */
127 | 80 |
        protected double samplingVariance( double r, double numsamples ) {
128 |  |
129 | 0 |
           if ( numsamples <= 0 ) throw new IllegalArgumentException( "N must be greater than 0" );
130 |  |
131 | 80 |
           if ( !CorrelationStats.isValidPearsonCorrelation( r ) )
132 | 0 |
                 throw new IllegalArgumentException( "r=" + r + " is not a valid Pearson correlation" );
133 |  |
134 | 80 |
           double FUDGE = 0.001;
135 | 80 |
           if ( Math.abs( r ) - 1.0 < FUDGE ) {
136 | 80 |
              r = Math.abs( r ) - FUDGE; // don't care about sign. any more.
137 |  |
           }
138 |  |
139 | 80 |
           if ( numsamples < 2 ) {
140 | 0 |
              return Double.NaN;
141 |  |
           }
142 | 80 |
           double k = 1.0 - r * r;
143 | 80 |
           double var = k * k / ( numsamples - 1 );
144 |  |
145 | 80 |
           return var;
146 |  |
        }
147 |  |
148 |  |
        /**
149 |  |
         * Run equation CH 18-10 on a list of sample sizes and effects.
150 |  |
         *
151 |  |
         * @param effectSizes
152 |  |
         * @param sampleSizes
153 |  |
         * @see samplingVariance
154 |  |
         * @return
155 |  |
         */
156 | 4 |
        protected DoubleArrayList samplingVariances( DoubleArrayList effectSizes, DoubleArrayList sampleSizes ) {
157 |  |
158 | 0 |
           if ( effectSizes.size() != sampleSizes.size() ) throw new IllegalArgumentException( "Unequal sample sizes." );
159 |  |
160 | 4 |
           DoubleArrayList answer = new DoubleArrayList( sampleSizes.size() );
161 | 4 |
           for ( int i = 0; i < sampleSizes.size(); i++ ) {
162 |  |
163 | 80 |
              double ef = effectSizes.getQuick( i );
164 |  |
165 | 80 |
              if ( Double.isNaN( ef ) ) {
166 | 0 |
                 answer.add( Double.NaN );
167 |  |
              } else {
168 | 80 |
                 answer.add( samplingVariance( ef, sampleSizes.getQuick( i ) ) );
169 |  |
              }
170 |  |
           }
171 | 4 |
           return answer;
172 |  |
        }
173 |  |
174 |  |
        /**
175 |  |
         * Equation 18-8 from CH. For z-transformed correlations.
176 |  |
         *
177 |  |
         * <pre>
178 |  |
         * v_i = 1 / ( n_i - 3 )
179 |  |
         * </pre>
180 |  |
         *
181 |  |
         * @param n
182 |  |
         * @return
183 |  |
         */
184 | 100 |
        protected double fisherTransformedSamplingVariance( double sampleSize ) {
185 |  |
186 | 0 |
           if ( sampleSize <= 3.0 ) throw new IllegalStateException( "N is too small" );
187 |  |
188 | 100 |
           return 1.0 / ( sampleSize - 3.0 );
189 |  |
        }
190 |  |
191 |  |
        /**
192 |  |
         * Run equation CH 18-8 on a list of sample sizes.
193 |  |
         *
194 |  |
         * @param sampleSizes
195 |  |
         * @return
196 |  |
         */
197 | 5 |
        protected DoubleArrayList fisherTransformedSamplingVariances( DoubleArrayList sampleSizes ) {
198 |  |
199 | 5 |
           DoubleArrayList answer = new DoubleArrayList( sampleSizes.size() );
200 | 5 |
           for ( int i = 0; i < sampleSizes.size(); i++ ) {
201 | 100 |
              answer.add( fisherTransformedSamplingVariance( sampleSizes.getQuick( i ) ) );
202 |  |
           }
203 | 5 |
           return answer;
204 |  |
        }
205 |  |
206 | 0 |
        public void setFixed( boolean fixed ) {
207 | 0 |
           this.fixed = fixed;
208 |  |
        }
209 |  |
210 | 0 |
        public void setTransform( boolean transform ) {
211 | 0 |
           this.transform = transform;
212 |  |
        }
213 |  |
214 | 0 |
        public double getP() {
215 | 0 |
           return p;
216 |  |
        }
217 |  |
218 | 1 |
        public double getQ() {
219 | 1 |
           return q;
220 |  |
        }
221 |  |
222 | 2 |
        public double getZ() {
223 | 2 |
           return z;
224 |  |
        }
225 |  |
226 | 2 |
        public double getE() {
227 | 2 |
           return e;
228 |  |
        }
229 |  |
230 | 2 |
        public double getV() {
231 | 2 |
           return v;
232 |  |
        }
233 |  |
234 | 0 |
        public double getN() {
235 | 0 |
           return n;
236 |  |
        }
237 |  |
238 | 2 |
        public double getBsv() {
239 | 2 |
           return bsv;
240 |  |
        }
241 |  |
     }