package edu.harvard.wcfia.yoshikoder.reporting; import java.text.NumberFormat; import javax.swing.text.NumberFormatter; /** * Computes and records various statistics relating to the risk ratio. * Quantities are stored as logs and exponentiated on demand. * * @author will * */ public class RiskRatioStatistics{ protected double p1, p2, N1, N2, logRR, seLogRR; protected boolean allBetsAreOff; // we have a zero in the works... public RiskRatioStatistics(int map1count, int map1Total, int map2count, int map2Total){ if ((map1count == 0.0) || (map1Total == 0.0) || (map2count == 0.0) || (map2Total == 0.0)) allBetsAreOff = true; else { N1 = map1Total; N2 = map2Total; p1 = (double)map1count / N1; p2 = (double)map2count / N2; seLogRR = Math.sqrt( (1-p1) / (N1*p1) + (1-p2) / (N2*p2) ); logRR = Math.log(p1) - Math.log(p2); System.err.println(logRR); } } public double getLogRiskRatio() throws UncomputableRiskRatioException { if (allBetsAreOff) throw new UncomputableRiskRatioException("Cannot compute risk ratio"); return logRR; } public double[] getLogRiskRatioInterval(double z) throws UncomputableRiskRatioException { if (allBetsAreOff) throw new UncomputableRiskRatioException("Cannot compute risk ratio"); return new double[]{ logRR - z*seLogRR, logRR + z*seLogRR }; } public double[] getLogRiskRatio95Interval() throws UncomputableRiskRatioException { if (allBetsAreOff) throw new UncomputableRiskRatioException("Cannot compute risk ratio"); return getLogRiskRatioInterval(1.96); } public double getRiskRatio() throws UncomputableRiskRatioException { if (allBetsAreOff) throw new UncomputableRiskRatioException("Cannot compute risk ratio"); return Math.exp(logRR); } /** * Gets upper and lower ends of a 95% interval for the risk ratio. Computed * using 1.96 as the z score. * @return 95% confidence interval */ public double[] getRiskRatio95Interval() throws UncomputableRiskRatioException{ if (allBetsAreOff) throw new UncomputableRiskRatioException("Cannot compute risk ratio"); double[] lrrInterval = getLogRiskRatio95Interval(); return new double[]{Math.exp(lrrInterval[0]), Math.exp(lrrInterval[1])}; } /** * States whether an interval excludes the specified value. For * example, whether a risk raio interval excludes 1 (no effect). * @param value * @param interval * @return whether the interval excludes the value */ public boolean intervalExcludes(double value, double[] interval){ return ((interval[0] > value && interval[1] > value) || (interval[0] < value && interval[1] < value)); } public String toString(){ if (allBetsAreOff) return "NA"; else { NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(4); try { StringBuffer sb = new StringBuffer(); sb.append(nf.format(getRiskRatio())); sb.append(" ["); double[] interval = getRiskRatio95Interval(); sb.append( nf.format(interval[0]) ); sb.append(", "); sb.append( nf.format(interval[1]) ); sb.append("]"); if (intervalExcludes(1, interval)) sb.append(" *"); return sb.toString(); } catch (UncomputableRiskRatioException urre){ return "NA"; } } } public static void main(String[] args) { int c1 = 11; int N1 = 25; int c2 = 3; int N2 = 34; RiskRatioStatistics rrs = new RiskRatioStatistics(c1, N1, c2, N2); System.out.println(rrs); } }