Wednesday, July 22, 2009

Fisher's Exact Test

I'm still working on this project for Dr. Johnson.
I looked forever on the internet for a java implementation of the Fisher's Exact test, but couldn't find any, although I did find some pages with dead links on them...

So I sat down and did it.
Here's what I came up with:


public class Fisher
{
/**
* Gets the p-value for the given table
* pos neg
* in a b
* out c d n = a+b+c+d
*
* p = (a+b)!(c+d)!(a+c)!(b+d)!
* ------------------------
* n! a! b! c! d! (from http://en.wikipedia.org/wiki/Fisher%27s_exact_test)
*
* p = (a+b)!(b+d)!(c+a)!(d+c)!
* ------------------------
* n! a! b! c! d! (Rearrangement of sums and products)
*
* notation x@y = ((x+1)*(x+2)*...*(x+y)), e.g. 0@y = y!
*
* p = (a@b)(b@d)(c@a)(d@c) (x+y)!
* ------------------------ ( ------ = x@y )
* n! x!
*
*
*
* notation L@(x,y) = (ln(x+1)+ln(x+2)+...+ln(x+y))
*
* ln(p) = L@(a,b) + L@(b,d) + L@(c,a) + L@(d,c) - ( L@(0,n) )
*
* p = e ^ [L@(a,b) + L@(b,d) + L@(c,a) + L@(d,c) - ( L@(0,n) )]
*
* @return the p-value for this table
*/
private static double getPValue(int a, int b, int c, int d)
{
int n = a + b + c + d;
return Math.exp(getLogSum(a,b) + getLogSum(b,d) + getLogSum(c,a) + getLogSum(d,c) - getLogSum(0,n));
}



/**
* Gets the fisher's p-value cutoff for a point
*/
private static double getFishersExactPValue(int a, int b, int c, int d)
{
double p_cutoff = getPValue(a,b,c,d);
System.out.println("Got for: " + printTable(a,b,c,d) + p_cutoff);
double leftSide = getLeftSidePs(a, b, c, d, p_cutoff) + p_cutoff;
double rightSide = getRightSidePs(a, b, c, d, p_cutoff) + p_cutoff;
double twoSided = p_cutoff + leftSide + rightSide;
System.out.println("sides: left: " + leftSide + " right: " + rightSide);
return twoSided;
}

/**
* Gets the sum of the p-values for tables on the left side of the given table
* that are smaller than the cutoff value
*/
private static double getLeftSidePs(int a, int b, int c, int d,
double p_cutoff)
{
double sumOfLeftTables = 0;

while(c > 0 && b > 0)
{
a++;
b--;
c--;
d++;
double thisP = getPValue(a,b,c,d);
if (thisP <= p_cutoff)
sumOfLeftTables += thisP;
System.out.println("left tried: " + printTable(a,b,c,d) + getPValue(a,b,c,d));
}
return sumOfLeftTables;
}

/**
* Gets the sum of the p-values for tables on the right side of the given table
* that are smaller than the cutoff value
*/
private static double getRightSidePs(int a, int b, int c, int d,
double p_cutoff)
{
double sumOfRightTables = 0;

while(a > 0 && d > 0)
{
a--;
b++;
c++;
d--;
double thisP = getPValue(a,b,c,d);
if (thisP <= p_cutoff)
sumOfRightTables += thisP;
System.out.println("right tried: " + printTable(a,b,c,d) + getPValue(a,b,c,d));
}
return sumOfRightTables;
}

/**
* Prints the given table
*/
private static String printTable(int a, int b, int c, int d)
{
String retString = "\n|" + a + "\t" + b + "\t|\n";
retString += "|" + c + "\t" + d + "\t|\n";
return retString;
}

/**
* Returns (a+1)+(a+2)..+(a+b) = factorial in log land
* @return the sum of the log of numbers from a to a+b
*/
private static double getLogSum(int a, int b)
{
double sum = 0;
for (int i = a + 1; i <= a + b; i++)
{
sum += Math.log(i);
}
return sum;
}

public static void main(String[] args)
{
double val = getFishersExactPValue(2,3,4,5);
System.out.println("val: " + val);
}

}


And the best part, is that Wolfram agrees with my calculations, as does this online calculator.

Thursday, July 9, 2009

July 4

Here's a shout out for Independence day.

Last summer I spent July 4 in another country.. probably Germany. The year before that, I was in DC and watched the Capitol Fourth with Ben, Alisha, Adam, and Cassie. What a blast.

But this year was great. I spent it with family and friends. Which is the way July 4th should be spent.

A text was widely propagated that told people that Old Navy shirts were for $1, which turned out to be a joke on Old Navy. Tyler, Sean, and I drove over and arrived a minute before it closed. Only extra-large shirts were left, so we got wife-beaters with the flag on them, then drove home in the geo. We flipped it into convertible mode by popping the trunk, which increased the head room, and blasted the mexitunes. It was rocking.

July 3, we had a little shindig at our house. We did smores and played pool and socialized with a bunch of people. Sean and I set up the projector with a sheet hung from the swing set in the back yard. While we were waiting for people to come, we got some halo on. I was leading 3-0 when it started to rain. So we all went in and watched Italian Job.

The movie ended at 5:00 am... I fell asleep until 8:30, and a bunch of friends and I went over to free french toast at Maceys.. mmm sooo good. And it was free. Then we walked back and watched the parade on the front lawn. Grandma and Grandpa and Randall came over, and found spots on the lawn. It was pretty sweet. I'll admit I almost teared up when the trucks rolled by with the soldiers. I am proud of them and people who have pride in our country.

Then I headed up to Milo to see Dev and picked up Gabe on the way. We talked a lot. He gave me some insides on being married that were .... nice. I got a new backpack from nixon. It's pretty sweet. Lots of room for clothes and other things when people are traveling to other countries.

Then I drove the family up to Alisa's and we had a good barbecue. Grandma and Grandpa did shishkabobs as I remember them from when I was a little kid. And Mom made a killer acini salad. And Tia Sue's rolls were to die for. It was incredible. Then, I played baseball with some of Dan's kids while Alisa dashed off to get ready for her concert.

We found parking spots close to the concert, and Grandma had saved our families one blanket-spot. We gradually spread out like a zerg creep because the other blankets were uninhabited.

The music was light and entertaining, and I loved to just lay on the grass in the warm summer air, listening to the music and staring up into the deep blue sky, watching it turn red then gray.

Then came the 1812 overture and the cannons from across the way caught everyone's attention. And then came the fireworks. As the fireworks shot off, patriotic songs played, and I was proud. It gradually got darker and cooler, and I snuggled up with Zach in grandma's jean blanket. It was great having my family around me. The little kids oohed and ahed at the fireworks, and ran around with glow sticks.

Then with a huge finale, it was over. And everyone headed home. I got to drive Grandma and Grandpa's new Equinox home. I'm not sure how good their eyesight is getting at night. Mom and Dad acted like it was precautionary measure. But it was fun to talk to them. Grandma got a car before her dad did. They just got rides around Huntington. I come from good stock.

And then we came home and I slept over at the house, getting up for church the next day at 1:00pm.

What a weekend.

I'll have to see what happens next year... unfortunately, there's that bull run...