Implemented the McNemar test. Closes bug #33242
[pspp-builds.git] / src / language / stats / npar.c
index d34ec11932e5ffdd204b00f8a1fe850b3b873821..ce0c3d6d06419fecdad91ca79666de840dcbe42a 100644 (file)
@@ -38,6 +38,7 @@
 #include "language/stats/friedman.h"
 #include "language/stats/kruskal-wallis.h"
 #include "language/stats/mann-whitney.h"
+#include "language/stats/mcnemar.h"
 #include "language/stats/npar-summary.h"
 #include "language/stats/runs.h"
 #include "language/stats/sign.h"
@@ -89,6 +90,7 @@ struct cmd_npar_tests
     int kendall;
     int kruskal_wallis;
     int mann_whitney;
+    int mcnemar;
     int missing;
     int method;
     int statistics;
@@ -132,6 +134,7 @@ static int npar_wilcoxon (struct lexer *, struct dataset *, struct npar_specs *)
 static int npar_sign (struct lexer *, struct dataset *, struct npar_specs *);
 static int npar_kruskal_wallis (struct lexer *, struct dataset *, struct npar_specs *);
 static int npar_mann_whitney (struct lexer *, struct dataset *, struct npar_specs *);
+static int npar_mcnemar (struct lexer *, struct dataset *, struct npar_specs *);
 static int npar_method (struct lexer *, struct npar_specs *);
 
 /* Command parsing functions. */
@@ -148,6 +151,7 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests
   npt->friedman = 0;
   npt->kruskal_wallis = 0;
   npt->mann_whitney = 0;
+  npt->mcnemar = 0;
   npt->runs = 0;
   npt->sign = 0;
   npt->wilcoxon = 0;
@@ -276,6 +280,23 @@ parse_npar_tests (struct lexer *lexer, struct dataset *ds, struct cmd_npar_tests
               NOT_REACHED ();
             }
         }
+      else if (lex_match_phrase (lexer, "MCNEMAR"))
+        {
+          lex_match (lexer, T_EQUALS);
+          npt->mcnemar++;
+          switch (npar_mcnemar (lexer, ds, nps))
+            {
+            case 0:
+              goto lossage;
+            case 1:
+              break;
+            case 2:
+              lex_error (lexer, NULL);
+              goto lossage;
+            default:
+              NOT_REACHED ();
+            }
+        }
       else if (lex_match_phrase (lexer, "M-W") ||
               lex_match_phrase (lexer, "MANN-WHITNEY"))
         {
@@ -1045,8 +1066,6 @@ npar_wilcoxon (struct lexer *lexer,
               struct dataset *ds,
               struct npar_specs *specs )
 {
-
-
   struct two_sample_test *tp = pool_alloc (specs->pool, sizeof (*tp));
   struct npar_test *nt = &tp->parent;
   nt->execute = wilcoxon_execute;
@@ -1090,6 +1109,8 @@ npar_mann_whitney (struct lexer *lexer,
 }
 
 
+
+
 static int
 npar_sign (struct lexer *lexer, struct dataset *ds,
           struct npar_specs *specs)
@@ -1112,6 +1133,30 @@ npar_sign (struct lexer *lexer, struct dataset *ds,
   return 1;
 }
 
+
+static int
+npar_mcnemar (struct lexer *lexer, struct dataset *ds,
+          struct npar_specs *specs)
+{
+  struct two_sample_test *tp = pool_alloc (specs->pool, sizeof (*tp));
+  struct npar_test *nt = &tp->parent;
+
+  nt->execute = mcnemar_execute;
+
+  if (!parse_two_sample_related_test (lexer, dataset_dict (ds),
+                                     tp, specs->pool) )
+    return 0;
+
+  specs->n_tests++;
+  specs->test = pool_realloc (specs->pool,
+                             specs->test,
+                             sizeof (*specs->test) * specs->n_tests);
+  specs->test[specs->n_tests - 1] = nt;
+
+  return 1;
+}
+
+
 static int
 npar_kruskal_wallis (struct lexer *lexer, struct dataset *ds,
                      struct npar_specs *specs)