[Home] Restricted access for guests. The link to Java source code is disabled
Java source code of 'jhplot.stat.Anova'
//Computes 1-way ANOVA -- just pass in data into constructor
//getP(), getF(), etc return the stats you want...
package jhplot.stat;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Vector;
import java.lang.Math;
/**
* Class for performing simple 1-way ANOVA. For multi-way ANOVA, try
* mathematica.
*
* @author Jacob Eisenstein
* @version 1.0
*/
public class Anova {
/**
* Creates a new Anova instance. Pass in the samples as an
* array of double arrays. Naturally, they may have different sizes.
*
* @param p_data
* a double[][] value
*/
public Anova(double[][] p_data) {
data = p_data; // maybe do a deep copy?
double s_between = 0f;
double s_residual = 0f;
double all_means[] = new double[p_data.length];
double overall_mean = 0f;
int total_size = 0;
int all_sizes[] = new int[p_data.length];
Arrays.fill(all_means, 0f);
Arrays.fill(all_sizes, 0);
// System.out.println ("pdata.length = "+p_data.length);
for (int i = 0; i < p_data.length; i++) {
// Vector cur_group = (Vector) all_groups.elementAt(i);
// double group_distrib[] = new double[p_data[i].length];
if (p_data == null)
System.out.println("pdata null");
if (p_data[i] == null)
System.out.println("pdata[" + i + "] null");
all_sizes[i] = p_data[i].length;
total_size += all_sizes[i];
for (int j = 0; j < p_data[i].length; j++) {
if (!Double.isNaN(p_data[i][j]))
all_means[i] += p_data[i][j] / all_sizes[i];
overall_mean += p_data[i][j];
}
for (int j = 0; j < p_data[i].length; j++) {
if (!Double.isNaN(p_data[i][j]))
s_residual += Math.pow(p_data[i][j] - all_means[i], 2);
}
}
overall_mean /= total_size;
// double overall_mean = weka.core.Utils.mean (all_means);
for (int i = 0; i < p_data.length; i++) {
s_between += all_sizes[i]
* Math.pow(all_means[i] - overall_mean, 2);
}
dof1 = p_data.length - 1;
dof2 = total_size - p_data.length;
f = (s_between / (double) dof1) / (s_residual / (double) dof2);
// System.out.println (f+"\t"+dof1+"\t"+dof2);
p = Statistics.FProbability(f, dof1, dof2);
}
/**
* Prettyprints your data and the results of the ANOVA.
*
*/
public void printData() {
System.out.println("---------------------------------------");
DecimalFormat df = new DecimalFormat("0.0000");
Vector all_data = new Vector();
for (int i = 0; i < data.length; i++) {
System.out.print(df.format(Statistics.mean(data[i])) + " "
+ df.format(Math.sqrt(Statistics.variance(data[i])))
+ " |");
for (int j = 0; j < data[i].length; j++) {
if (!Double.isNaN(data[i][j])) {
System.out.print(" " + df.format(data[i][j]));
all_data.add(new Double(data[i][j]));
}
}
System.out.println();
}
System.out.println(" -------------------");
double[] vall_data = new double[all_data.size()];
for (int i = 0; i < all_data.size(); i++) {
vall_data[i] = ((Double) (all_data.elementAt(i))).doubleValue();
}
System.out.println(df.format(Statistics.mean(vall_data)) + " "
+ df.format(Math.sqrt(Statistics.variance(vall_data)))
+ " |");
System.out.println("-----------------------------------------");
}
/**
* Pretty prints your results.
*
*/
public void printResults() {
System.out.println("F=" + getF() + " DOF1=" + getDOF1() + " DOF2="
+ getDOF2() + " P=" + getP());
}
/**
* Returns the p-value that your data is all drawn from a single
* distribution. Lower p means you have an effect that is more
* likely to be significant.
*
* @return a double value
*/
public double getP() {
return p;
}
/**
* Returns the F-value for your data. Sometimes people like to give this
* along with the p-value in publications.
*
* @return a double value
*/
public double getF() {
return f;
}
/**
* The first degree of freedom is equal to the number of sample groups,
* minus 1.
*
* @return an int value
*/
public int getDOF1() {
return dof1;
}
/**
* The second degree of freedom is equal to the total number of data points,
* minus the number of samples.
*
* @return an int value
*/
public int getDOF2() {
return dof2;
}
/**
* Returns an array of means for all of your sample groups.
*
* @return a double[] value
*/
public double[] getMeans() {
double means[] = new double[data.length];
for (int i = 0; i < means.length; i++) {
for (int j = 0; j < data[i].length; j++) {
if (!Double.isNaN(data[i][j]))
means[i] += data[i][j];
}
means[i] /= data[i].length;
}
return means;
}
/**
* This takes a input array and produces matlab code that can be coppied
* directly into a matlab prompt to run anova on it
*/
private static String makeMatlab(double[][] m) {
StringBuffer mat = new StringBuffer("a = [");
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
mat.append(i + " " + m[i][j] + "; ");
}
}
mat.append("];\n");
mat.append("anova1(a(:,2)',a(:,1)')");
return mat.toString();
}
/**
* A sample set that gives different answers than Matlab.
**/
private static void test() {
double[][] i_data = new double[][] {
{ 0.000583 },
{ 0.000117, 0.001011, 0.00019, 0.003418, 0.000445, 0.000472,
7.942658E-005, 1.861884E-005, 0.000719, 0.000386,
0.00034, 0.000994, 0.001243, 0.000481, 0.001052 },
{ 0.000271, 0.00063, 0.000195, 3.091709E-005, 0.001265,
0.001154, 0.001111, 0.001169, 0.000982, 0.009851,
0.000214, 0.000318, 0.000565, 0.004859, 0.006513,
0.007501, 0.010925, 0.000653, 0.000687, 1.808875E-005,
0.0004, 0.000102, 0.000122, 0.00731, 0.000329,
0.000738, 0.000232, 0.000317, 0.000104, 0.000187,
9.65759E-005, 8.779085E-005, 0.000267, 0.000666,
0.000213, 0.001207, 5.800928E-005, 0.000146, 0.00021,
0, 4.213974E-005, 0.000296, 7.076694E-005, 0.000451,
0.0002, 0.004935, 0.003804, 0.000863, 0.000567,
0.000737, 0.000631, 0.003083, 0.000357, 0.001986,
0.000435, 0.003722, 9.99448E-005, 0.000448, 0.001421,
0.024937, 0.000404, 0.000192, 0.000456, 5.722088E-005,
0.0025, 0.000147, 0.003904, 0.001772 },
{ 0.001321, 0.000156, 2.353968E-005, 0.000992, 0.000576,
1.557194E-005, 0.002012, 0.000501, 0.000527 },
{ 0.000587, 0.000224, 0.0002, 0.000483, 0.00058, 3.929909E-005,
0.002227, 0.000543, 3.626242E-005, 0.000224, 0.000256,
0.00023, 0.000526, 0.002585 }, };
Anova an = new Anova(i_data);
System.out.println(an.getP());
an.printData();
an.printResults();
System.out.println(makeMatlab(i_data));
}
/**
* This will reproduce the "hotdog" example from De Groot & Schervish's
* "Probability and Statistics", page 666.
**/
private static void hotDogTest() {
double i_data[][] = new double[4][];
double data1[] = { 186, 181, 176, 149, 184, 190, 158, 139, 175, 148,
152, 111, 141, 153, 190, 157, 131, 149, 135, 132 };
double data2[] = { 173, 191, 182, 190, 172, 147, 146, 139, 175, 136,
179, 153, 107, 195, 135, 140, 138 };
double data3[] = { 129, 132, 102, 106, 94, 102, 87, 99, 107, 113, 135,
142, 86, 143, 152, 146, 144 };
double data4[] = { 155, 170, 114, 191, 162, 146, 140, 187, 180 };
i_data[0] = data1;
i_data[1] = data2;
i_data[2] = data3;
i_data[3] = data4;
Anova an = new Anova(i_data);
System.out.println(an.getP());
an.printData();
an.printResults();
System.out.println(makeMatlab(i_data));
}
protected double data[][];
protected double p;
protected double f;
protected int dof1;
protected int dof2;
public static void main(String argv[]) {
test();
// hotDogTest();
}
}