/* Student's t-Test Applet 11.June, 1997 Bryan Lewis Department of Mathematics and Computer Science Kent State University url: http://www.mcs.kent.edu/~blewis email: blewis@mcs.kent.edu The first in a set of simple statistics applets, tTest computes a one tailed Student's t test for data supplied in a text component. The data can be delimited with commas, tabs, spaces or newlines. This is my firs Java applet! JVM AWT: 1.02 This software is in the public domain and can be used, modified and distributed without restriction. Needs the following classes: tTest.class the applet itself editor.class the data editor object (that this frame extends) Matrix.class some linear algebra methods specialFunctions.class some special functions History: 11.June, 1997: First version 15.August, 1997: Modified to take advantage of the Matrix.class 12.December, 1997: Split up class source codes into separate files 24.December, 1997: implemented data editor object */ import java.awt.*; import java.lang.*; public class tFrame extends editor { Button button = new Button("Compute"); Button example = new Button("Example data"); Button quit = new Button("Close"); Label label = new Label("Data set 1"); specialFunctions sf = new specialFunctions(); // (specialFunctions is a library of functions, including the t-distribution) String newln = System.getProperty("line.separator"); // system-independent line terminator public tFrame(String title) { // constructor method (set up frame) super(title); Panel cPanel = new Panel(); // control panel at bottom Panel p = new Panel(); cPanel.setLayout(new GridLayout(1,2,2,2)); // 1r x 2c button.setBackground(Color.white); p.add(button); example.setBackground(Color.white); p.add(example); quit.setBackground(Color.white); p.add(quit); cPanel.add(p); add("South",cPanel); resize(460,425); show(); } public boolean handleEvent(Event e) { switch (e.id){ case Event.WINDOW_DESTROY: this.dispose(); default: return super.handleEvent(e); } } public boolean action(Event e, Object arg) { if (e.target == button) { // calculate the result result.setText("Calculating..."); Matrix D = new Matrix(data.getText()); // get the data Matrix A = D.sub(0,D.rows-1,0,0); // get column 1 Matrix B = D.sub(0,D.rows-1,1,1); // get column 2 result.setText(compute(A, B)); } else if (e.target == example) { // display some example data ExampleData exampleData = new ExampleData( (int) (Math.random() * 6 + 1)); data.setText(exampleData.example); } else if (e.target == quit) { this.dispose(); } return super.action(e, arg); } public String compute(Matrix A, Matrix B) { // First, set up the random variables randomVar rv1 = new randomVar(); rv1.mean = A.average(); rv1.sumSquares = A.sumSquares(); rv1.n = A.rows; randomVar rv2 = new randomVar(); rv2.mean = B.average(); rv2.sumSquares = B.sumSquares(); rv2.n = B.rows; double sv1 = 0; // 1st dataset sample variance double sv2 = 0; // 2nd dataset sample variance // sample--not pop. variance is calculated below sv1 = (rv1.sumSquares / rv1.n - rv1.mean * rv1.mean) * (rv1.n / (rv1.n - 1)); sv2 = (rv2.sumSquares / rv2.n - rv2.mean * rv2.mean) * (rv2.n / (rv2.n - 1)); /* Now it remains to be determined if the population variances can be pooled or not. To see this, an F-test can be applied to them. This decision is determined automatically, with an alpha level of 1%, in order to not encumber the user with details. */ double f = 0; double fAlpha = 0; if (sv1 > sv2) { f = sv1/sv2; fAlpha = sf.fDist(rv1.n - 1, rv2.n - 1, f); } else { f = sv2/sv1; fAlpha = sf.fDist(rv2.n - 1, rv1.n - 1, f); } double df = 0; // t Test degrees of freedom double t = 0; // t value String comment = new String(); String comment1 = new String(); if (fAlpha <= 0.005) { comment = "An F test on the sample variances indicates that they are " + newln + "probably not from the same population (the variances " + newln + "can't be pooled), at an alpha level of " + fAlpha + "." + newln + "Thus, the t-test was set up for samples with unequal varainces. "+ newln + "(The degrees of freedom were adjusted.)"; double svn1 = sv1 / rv1.n; double svn2 = sv2 / rv2.n; df = Math.pow(svn1 + svn2, 2) / (Math.pow(svn1, 2)/(rv1.n + 1) + Math.pow(svn2, 2)/(rv2.n + 1)) - 2; t = Math.abs(rv1.mean - rv2.mean) / Math.sqrt(sv1 / rv1.n + sv2 / rv2.n); } else { comment = "An F test on the sample variances indicates that they could be " + newln + "from the same population, (alpha level of 0.005)." + newln + "Accordingly, the t-test was set up for samples with equal population variance."; df = rv1.n + rv2.n - 2; double sp = Math.sqrt( ((rv1.n - 1)*sv1 + (rv2.n - 1)*sv2) / (rv1.n + rv2.n - 2) ); t = Math.abs(rv1.mean - rv2.mean) * Math.sqrt(rv1.n * rv2.n / (rv1.n + rv2.n)) / sp; } double pVal = sf.stDist(df, t); String pValComment = "" + pVal; if (pVal <= 0.01) { comment1 = "This probability indicates that there is a difference in sample means."; if (pVal <= 0.0001) { pValComment = "< 0.0001"; } } else if (pVal <= 0.05) { comment1 = "This probability indicates that there may be a difference in sample means."; } else { comment1 = "There is not a significant difference in the sample means. " + newln + "A difference could not be detected due to large variability, small sample size, " + newln + "or both. Of course, it's possible that the samples really are from the same population!"; } // a hack to take care of garbage data if ( (rv1.n == 0)||(rv2.n == 0) ) { comment1 = "There is a problem with the data. Valid delimiters are space, " + newln + "comma, tab and newline."; comment = ""; } // convert variance to std. deviation for report sv1 = Math.sqrt(sv1); sv2 = Math.sqrt(sv2); // build the report char tab = (char) 9; String cs = "Student's t-Test for Comparing Things " + newln + "Java Implementation by Bryan Lewis, Kent State University, 1997 " + newln + "This test determines if there is a significant "+ newln + "difference between " + "the averages of the two samples above. " + newln + newln + "Mean of first data set :" + tab + rv1.mean + newln + "Standard deviation of first data set :" + tab + sv1 + newln + "Number of observations in the first set :" + tab + rv1.n + newln + "Mean of second data set :" + tab + rv2.mean + newln + "Standard deviation of second data set :" + tab + sv2 + newln + "Number of observations in the second set :" + tab + rv2.n + newln + newln + "Degrees of freedom :" + tab + df + newln + "t Value (one-tailed) :" + tab + t + newln + "P(x>t) :" + tab + pValComment + newln + newln + comment1 + newln + newln + comment ; return cs; } } class randomVar { // a generic random variable double mean; double sumSquares; double n; }