Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How would I perform a chi-square goodness of fit test? I have tried the following, where my data consists of the observed values whilst the data pair contains the correct values. Then I use the DistributionFitTest on the data and the data pair.

data = {115, 188, 97};
datapair = {100, 200, 100};
DistributionFitTest[datapair, data]

(* Out= 0.248213 *)

However the result I get is 0.248 and should be 0.216. Am I doing something wrong? And how would I measure the $\chi^2$ value?

share|improve this question
How did you get the 0.216 value, first of all? – J. M. May 15 '12 at 12:30
I used Maple 15, however I'm opting for learning Mathematica. – Frederik Brinck Jensen May 15 '12 at 12:44
So, this command, then? – J. M. May 15 '12 at 12:47
Exactly! How would I do so in Mathematica? – Frederik Brinck Jensen May 15 '12 at 12:59
(1) What do these data mean? Are they counts? And how are the "correct" values obtained? If they are estimated from the data, that has to be taken into account. (2) Note that the order of the arguments given to DistributionFitTest is incorrect (but putting them in the correct order does not yield a correct test!). – whuber May 15 '12 at 13:32
up vote 15 down vote accepted

The name PearsonChiSquareTest has led to a bit of confusion for people wanting to test count/frequency data like these. In short, M just doesn't have this sort of test built in yet.

PearsonChiSquareTest and its equivalent call from DistributionFitTest have been derived according to the methods of D'Agostino and Stephens.

The test computes a maximum of Ceiling[2 n^(2/5)] equiprobable bins (where n is the data length) dropping bins that do not contain any data. These bins are used to compute observed and expected frequency histograms. The chi-square statistic is computed from the computed frequencies in the usual way. The Properties & Relations section of the PearsonChiSquareTest docs give more details on this.

Again, the important distinction is that this is a test for goodness of fit to a distribution with raw data and not a test for count/frequency data. If you want the latter it is easy to put together yourself.

pearsonTest[obs_List, exp_List] /; Length[obs] == Length[exp] :=
  t = Total[(obs - exp)^2/exp] // N;
 {Rule["chisqr", t], 
  Rule["p-val", SurvivalFunction[ChiSquareDistribution[Length[exp] - 1], t]]}  

pearsonTest[{115, 188, 97}, {100, 200, 100}]

==> {"chisqr" -> 3.06, "p-val" -> 0.216536}
share|improve this answer
Hah. I was scratching my head trying to reconcile the stuff in my textbook with the stuff in Mathematica's docs. Thanks for this! – J. M. May 15 '12 at 15:12
Thanks for this wonderful reply Andy! Can you give me any reference on where to read about the functions and the syntax of mathematica more deeply? – Frederik Brinck Jensen May 15 '12 at 18:56
@FrederikBrinckJensen you are welcome. I recommend looking at the following post – Andy Ross May 15 '12 at 19:07

A very good demonstration of contingency table hypothesis testing is here The following is a crude approach and formatting and style issues for presentation are a matter of taste. Apologies for errors and ugliness of code. It could be generalized for hypotheses other than marginal homogeneity ("additive" in the demonstration, This demonstration provides useful template for generating expected values based on particular null hypothesis).

For an r x c contingency table with null hypothesis of marginal homogeneity here is a code:

chi[u_] := 
Module[{dim, dof, rs, cs, n, full, exp, chis, restbl, tbl, exptbl, 
   pv, res},
  dim = Dimensions[u];
  dof = Times @@ (dim - 1);
  rs = Map[Plus @@ # &, u];
  cs = Map[Plus @@ # &, Transpose[u]];
  n = Total[Flatten[u]];
  full = Append[MapThread[Append[#1, #2] &, {u, rs}], Join[cs, {n}]];
  exp = Outer[Times, rs, cs]/n;
  chis = Total[Flatten[(u - exp)^2/exp]];
  restbl = 
   Grid[{{"Degrees of Freedom", dof}, {"Chi Square Statistic", 
      N[chis, 3]}, {"p-value", pv}}, Alignment -> {{Left, "."}}, 
    Frame -> All];
  tbl = Grid[full, 
    Background -> {None, 
      None, {{{dim[[1]] + 1, dim[[1]] + 1}, {1, dim[[2]] + 1}} -> 
        Pink, {{1, dim[[1]] + 1}, {dim[[2]] + 1, dim[[2]] + 1}} -> 
  exptbl = Grid[N[exp], Alignment -> {".", "."}];
  pv = N[SurvivalFunction[ChiSquareDistribution[dof], chis]];
  res = {"ChiSquareStatistic" -> N[chis, 2], "p-value" -> pv, 
    "result" -> restbl, "table" -> tbl, "expectedtable" -> exptbl, 
    "fullresults" -> 
     Column[{"Data Table", tbl, "Expected Values Table", exptbl, 
       "Hypothesis Testing", restbl}, Frame -> All, 
      Background -> {Yellow, None, Yellow, None, Yellow, None}], 
    "Properties" -> {"ChiSquareStatistic","p-value", "result", "table", 
      "expectedtable", "fullresults"}
  # /. res &
chisqt[u_, r_] := chi[u][r]

For example for table

x = {{50, 25, 15}, {25, 25, 35}, {15, 10, 35}, {10, 40, 55}};
chisqt[x, "table"] yields:

enter image description here

chisqt[x, "expectedtable"] yields:

enter image description here

chisqt[x, "result"] yields:

enter image description here

chisqt[x, "fullresults"] yields:

enter image description here

chisqt[x, "Properties"] yields:

{"ChiSquareStatistic","p-value", "result", "table", "expectedtable", "fullresults"}

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.