/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.statcato.statistics.inferential.nonparametrics;

import org.statcato.utils.HelperFunctions;
import org.statcato.utils.OrderingFunctions;
import org.statcato.statistics.NormalProbabilityDistribution;
import org.statcato.statistics.inferential.HypothesisTest;

import java.util.Vector;
import java.util.Iterator;

/**
 * Wilcoxon Rank Sum test.  A nonparametic test that uses ranks of
 * samples from two independent populations to test a claim about the medians 
 * of two populations.
 *
 * The two independent samples are combined into one sample, are sorted in
 * ascending order and are ranked based on its place in the one sample.
 * The sum of the ranks corresponding to one of the two samples are computed
 * and is used as test statistics.
 *
 * @author Margaret Yau
 * @version %I%, %G%
 * @since 1.0
 */
public class WilcoxonRankSumTest {
    /**
     * Sample size of the two samples
     */
    private int n1, n2;
    /**
     * Rank sum of sample 1
     */
    private double rankSum1;
    /**
     * Rank sum of sample 2
     */
    private double rankSum2;
    /**
     * The type of test
     */
    private int testType;
    /**
     * Significance of the test.
     */
    public double significance;

    /**
     * Constructor, given two samples of data values.
     *
     * @param data1 vector of double values (sample 1)
     * @param data2 vector of double values (sample 2)
     * @param testMedian hypothesized median
     * @param testType type of alternative hypothesis
     */
    public WilcoxonRankSumTest(Vector data1, Vector data2,
            int testType, double significance) {
        this.testType = testType;
        this.significance = significance;

        n1 = data1.size();
        n2 = data2.size();

        // calculates rank sum
        this.rankSum1 = getRankSum(data1, data2);
        this.rankSum2 = (n1 + n2) * (n1 + n2 + 1) / 2 - rankSum1;
    }

    /**
     * Returns the test statistic z = (R - mu) / sigma, where R is the
     * rank sum of the first same, mu the mean of the distribution of rank sum,
     * and sigma the standard deviatioin of the distribution of rank sum.
     *
     * @return test statistic z
     */
    public double testStatistic_R() {
        if (testType == HypothesisTest.LEFT_TAIL)
            return (rankSum1 - mu_R() + 0.5) / sigma_R();
        else
            return (rankSum1 - mu_R() - 0.5) / sigma_R();
    }

    /**
     * Returns the mean of the distribution of rank sum,
     * mu = n1 * (n1 + n2 + 1) / 2.
     *
     * @return mean
     */
    public double mu_R() {
        return n1 * (n1 + n2 + 1) / 2.0;
    }

    /**
     * Returns the standard deviation of the distribution of rank sum,
     * sigma = (n1 * n2 * (n1 + n2 + 1) / 12)^0.5
     *
     * @return standard deviation
     */
    public double sigma_R() {
        return Math.sqrt(n1 * n2 * (n1 + n2 + 1) / 12);
    }
    /**
     * Returns the p-value.  
     *
     * @return p-value
     */
    public double pValue_R() {
        
        NormalProbabilityDistribution dist =
                    new NormalProbabilityDistribution(0, 1);
        
        double p = dist.cumulativeProbability(testStatistic_R());

        if (testType == HypothesisTest.LEFT_TAIL)
            return p;
        else if (testType == HypothesisTest.RIGHT_TAIL)
            return 1 - p;
        else
            return 2 * (p <= 0.5? p:1-p);
    }

    public double criticalValue_R() {
        NormalProbabilityDistribution dist =
                new NormalProbabilityDistribution(0, 1);    // z distribution

        if (testType == HypothesisTest.RIGHT_TAIL)
            return dist.inverseCumulativeProbability(1 - significance);
        else if (testType == HypothesisTest.LEFT_TAIL)
            return dist.inverseCumulativeProbability(significance);
        else    // two tail
            return
                Math.abs(dist.inverseCumulativeProbability(significance / 2));
    }

    @Override
    public String toString() {
        String s = "";
        s += "Wilcoxon Rank Sum Test: 
"; s += ""; s += ""; s += "" + ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += ""; s += "
n1n2R1R2μRσRTest Statistics zRCritical Valuep-Value
" + n1 + "" + n2 + "" + rankSum1 + "" + rankSum2 + "" + HelperFunctions.formatFloat(mu_R(), 3) + "" + HelperFunctions.formatFloat(sigma_R(), 3) + "" + HelperFunctions.formatFloat(testStatistic_R(), 3) + "" + (testType == HypothesisTest.TWO_TAIL?"±":"")+ HelperFunctions.formatFloat(criticalValue_R(), 3) + "" + HelperFunctions.formatFloat(pValue_R(), 5) + "

"; return s; } /** * Returns the rank sum, which is the sum of ranks for the first sample. * Ranks are computed after the two samples are combined and sorted in * ascending order. * * @param data vector of Double values * @return rank sum */ public double getRankSum(Vector data1, Vector data2) { Vector dataVector = new Vector(); // fill DataValue vector with values from the two samples Iterator it = data1.iterator(); while (it.hasNext()) { Double next = (Double)it.next(); if (next != null) { dataVector.add(next); } } it = data2.iterator(); while (it.hasNext()) { Double next = (Double)it.next(); if (next != null) { dataVector.add(next); } } // compute ranks double[] ranks = OrderingFunctions.rankDoubleVector(dataVector); // compute the sums of ranks for sample 1 double rankSum = 0; for (int i = 0; i < data1.size(); ++i) { Double next = data1.elementAt(i); if (next != null) { rankSum += ranks[dataVector.indexOf(next)]; } } return rankSum; } }

Ads help maintain this website.