output: Introduce pivot tables.
[pspp] / src / language / stats / jonckheere-terpstra.c
index 86e705d25013cab24232433b26d8677a02a3027c..7e8406f38253e3a2b687d4625886313f57e03128 100644 (file)
 #include "libpspp/message.h"
 #include "libpspp/misc.h"
 #include "math/sort.h"
-#include "output/tab.h"
+#include "output/pivot-table.h"
 
 #include "gl/minmax.h"
 #include "gl/xalloc.h"
 
+#include "gettext.h"
+#define N_(msgid) msgid
+#define _(msgid) gettext (msgid)
+
+
 /* Returns true iff the independent variable lies in the
    between val1 and val2. Regardless of which is the greater value.
 */
@@ -49,7 +54,7 @@ include_func_bi (const struct ccase *c, void *aux)
   const struct n_sample_test *nst = aux;
   const union value *bigger = NULL;
   const union value *smaller = NULL;
-  
+
   if (0 > value_compare_3way (&nst->val1, &nst->val2, var_get_width (nst->indep_var)))
     {
       bigger = &nst->val2;
@@ -60,7 +65,7 @@ include_func_bi (const struct ccase *c, void *aux)
       smaller = &nst->val2;
       bigger = &nst->val1;
     }
-  
+
   if (0 < value_compare_3way (smaller, case_data (c, nst->indep_var), var_get_width (nst->indep_var)))
     return false;
 
@@ -74,7 +79,7 @@ struct group_data
 {
   /* The total of the caseweights in the group */
   double cc;
-  
+
   /* A casereader containing the group data.
      This casereader contains just two values:
      0: The raw value of the data
@@ -106,7 +111,7 @@ u (const struct group_data *grp0, const struct group_data *grp1)
         {
           double x1 = case_data_idx (c1, 0)->f;
           double cc1 = case_data_idx (c1, 1)->f;
-     
+
           if (x0 > x1)
             {
               /* Do nothing */
@@ -141,31 +146,31 @@ u (const struct group_data *grp0, const struct group_data *grp1)
 
 typedef double func_f (double e_l);
 
-/* 
-   These 3 functions are used repeatedly in the calculation of the 
+/*
+   These 3 functions are used repeatedly in the calculation of the
    variance of the JT statistic.
-   Having them explicitly defined makes the variance calculation 
+   Having them explicitly defined makes the variance calculation
    a lot simpler.
 */
-static  double 
+static  double
 ff1 (double e)
 {
   return e * (e - 1) * (2*e + 5);
 }
 
-static  double 
+static  double
 ff2 (double e)
 {
   return e * (e - 1) * (e - 2);
 }
 
-static  double 
+static  double
 ff3 (double e)
 {
   return e * (e - 1) ;
 }
 
-static  func_f *mff[3] = 
+static  func_f *mff[3] =
   {
     ff1, ff2, ff3
   };
@@ -181,7 +186,7 @@ static  func_f *mff[3] =
  */
 static
 void variance_calculation (struct casereader *ir, const struct variable *var,
-                           const struct dictionary *dict, 
+                           const struct dictionary *dict,
                            func_f **f, double *result, size_t n)
 {
   int i;
@@ -195,7 +200,7 @@ void variance_calculation (struct casereader *ir, const struct variable *var,
   r = sort_execute_1var (r, var);
 
   r = casereader_create_distinct (r, var, dict_get_weight (dict));
-  
+
   for (; (c = casereader_read (r)); case_unref (c))
     {
       double w = case_data_idx (c, w_idx)->f;
@@ -216,7 +221,8 @@ struct jt
   double stddev;
 };
 
-static void show_jt (const struct n_sample_test *nst, const struct jt *jt, const struct variable *wv);
+static void show_jt (const struct n_sample_test *, const struct jt *,
+                     const struct fmt_spec *wfmt);
 
 
 void
@@ -231,13 +237,13 @@ jonckheere_terpstra_execute (const struct dataset *ds,
   bool warn = true;
   const struct dictionary *dict = dataset_dict (ds);
   const struct n_sample_test *nst = UP_CAST (test, const struct n_sample_test, parent);
-  
+
   struct caseproto *proto = caseproto_create ();
   proto = caseproto_add_width (proto, 0);
   proto = caseproto_add_width (proto, 0);
 
   /* If the independent variable is missing, then we ignore the case */
-  input = casereader_create_filter_missing (input, 
+  input = casereader_create_filter_missing (input,
                                            &nst->indep_var, 1,
                                            exclude,
                                            NULL, NULL);
@@ -246,7 +252,7 @@ jonckheere_terpstra_execute (const struct dataset *ds,
   input = casereader_create_filter_weight (input, dict, &warn, NULL);
 
   /* Remove all those cases which are outside the range (val1, val2) */
-  input = casereader_create_filter_func (input, include_func_bi, NULL, 
+  input = casereader_create_filter_func (input, include_func_bi, NULL,
        CONST_CAST (struct n_sample_test *, nst), NULL);
 
   /* Sort the data by the independent variable */
@@ -271,14 +277,14 @@ jonckheere_terpstra_execute (const struct dataset *ds,
 
     /* Get a few values into e_sum - we'll be needing these later */
     variance_calculation (vreader, nst->vars[v], dict, mff, e_sum, 3);
-  
+
     grouper =
       casegrouper_create_vars (vreader, &nst->indep_var, 1);
 
     jt.obs = 0;
     jt.levels = 0;
     jt.n = 0;
-    for (; casegrouper_get_next_group (grouper, &group); 
+    for (; casegrouper_get_next_group (grouper, &group);
          casereader_destroy (group) )
       {
         struct casewriter *writer = autopaging_writer_create (proto);
@@ -336,85 +342,61 @@ jonckheere_terpstra_execute (const struct dataset *ds,
 
     jt.mean = (pow2 (jt.n) - ccsq_sum) / 4.0;
 
-    show_jt (nst, &jt, dict_get_weight (dict));
+    show_jt (nst, &jt, dict_get_weight_format (dict));
   }
 
   casereader_destroy (input);
   caseproto_unref (proto);
 }
-
 \f
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
 static void
-show_jt (const struct n_sample_test *nst, const struct jt *jt, const struct variable *wv)
+show_jt (const struct n_sample_test *nst, const struct jt *jt,
+         const struct fmt_spec *wfmt)
 {
-  int i;
-  const int row_headers = 1;
-  const int column_headers = 1;
-  const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : & F_8_0;
-
-  struct tab_table *table =
-    tab_create (row_headers + 7, column_headers + nst->n_vars);
-  tab_set_format (table, RC_WEIGHT, wfmt);
-
-  tab_headers (table, row_headers, 0, column_headers, 0);
-
-  tab_title (table, _("Jonckheere-Terpstra Test"));
-
-  /* Vertical lines inside the box */
-  tab_box (table, 1, 0, -1, TAL_1,
-          row_headers, 0, tab_nc (table) - 1, tab_nr (table) - 1 );
-
-  /* Box around the table */
-  tab_box (table, TAL_2, TAL_2, -1, -1,
-          0,  0, tab_nc (table) - 1, tab_nr (table) - 1 );
-
-  tab_hline (table, TAL_2, 0, tab_nc (table) -1, column_headers);
-  tab_vline (table, TAL_2, row_headers, 0, tab_nr (table) - 1);
-
-  tab_text_format (table, 1, 0, TAT_TITLE | TAB_CENTER,
-                   _("Number of levels in %s"),
-                   var_to_string (nst->indep_var));
-  tab_text (table, 2, 0, TAT_TITLE | TAB_CENTER, _("N"));
-  tab_text (table, 3, 0, TAT_TITLE | TAB_CENTER, _("Observed J-T Statistic"));
-  tab_text (table, 4, 0, TAT_TITLE | TAB_CENTER, _("Mean J-T Statistic"));
-  tab_text (table, 5, 0, TAT_TITLE | TAB_CENTER, _("Std. Deviation of J-T Statistic"));
-  tab_text (table, 6, 0, TAT_TITLE | TAB_CENTER, _("Std. J-T Statistic"));
-  tab_text (table, 7, 0, TAT_TITLE | TAB_CENTER, _("Asymp. Sig. (2-tailed)"));
-
-
-  for (i = 0; i < nst->n_vars; ++i)
+  struct pivot_table *table = pivot_table_create (
+    N_("Jonckheere-Terpstra Test"));
+  pivot_table_set_weight_format (table, wfmt);
+
+  struct pivot_dimension *statistics = pivot_dimension_create (
+    table, PIVOT_AXIS_COLUMN, N_("Statistics"));
+  pivot_category_create_leaf_rc (
+    statistics->root,
+    pivot_value_new_text_format (N_("Number of levels in %s"),
+                                 var_to_string (nst->indep_var)),
+    PIVOT_RC_INTEGER);
+  pivot_category_create_leaves (
+    statistics->root,
+    N_("N"), PIVOT_RC_COUNT,
+    N_("Observed J-T Statistic"), PIVOT_RC_OTHER,
+    N_("Mean J-T Statistic"), PIVOT_RC_OTHER,
+    N_("Std. Deviation of J-T Statistic"), PIVOT_RC_OTHER,
+    N_("Std. J-T Statistic"), PIVOT_RC_OTHER,
+    N_("Asymp. Sig. (2-tailed)"), PIVOT_RC_SIGNIFICANCE);
+
+  struct pivot_dimension *variables = pivot_dimension_create (
+    table, PIVOT_AXIS_ROW, N_("Variable"));
+
+  for (size_t i = 0; i < nst->n_vars; ++i)
     {
-      double std_jt;
-
-      tab_text (table, 0, i + row_headers, TAT_TITLE, 
-                var_to_string (nst->vars[i]) );
-
-      tab_double (table, 1, i + row_headers, TAT_TITLE, 
-                  jt[0].levels, NULL, RC_INTEGER);
-      tab_double (table, 2, i + row_headers, TAT_TITLE, 
-                  jt[0].n, NULL, RC_WEIGHT);
-
-      tab_double (table, 3, i + row_headers, TAT_TITLE, 
-                  jt[0].obs, NULL, RC_OTHER);
-
-      tab_double (table, 4, i + row_headers, TAT_TITLE, 
-                  jt[0].mean, NULL, RC_OTHER);
-
-      tab_double (table, 5, i + row_headers, TAT_TITLE, 
-                  jt[0].stddev, NULL, RC_OTHER);
-
-      std_jt = (jt[0].obs - jt[0].mean) / jt[0].stddev;
-      tab_double (table, 6, i + row_headers, TAT_TITLE, 
-                  std_jt, NULL, RC_OTHER);
-
-      tab_double (table, 7, i + row_headers, TAT_TITLE, 
-                  2.0 * ((std_jt > 0) ? gsl_cdf_ugaussian_Q (std_jt) : gsl_cdf_ugaussian_P (std_jt)), NULL, RC_PVALUE);
+      int row = pivot_category_create_leaf (
+        variables->root, pivot_value_new_variable (nst->vars[i]));
+
+      double std_jt = (jt[0].obs - jt[0].mean) / jt[0].stddev;
+      double sig = (2.0 * (std_jt > 0
+                           ? gsl_cdf_ugaussian_Q (std_jt)
+                           : gsl_cdf_ugaussian_P (std_jt)));
+      double entries[] = {
+        jt[0].levels,
+        jt[0].n,
+        jt[0].obs,
+        jt[0].mean,
+        jt[0].stddev,
+        std_jt,
+        sig,
+      };
+      for (size_t j = 0; j < sizeof entries / sizeof *entries; j++)
+        pivot_table_put2 (table, j, row, pivot_value_new_number (entries[j]));
     }
-  
-  tab_submit (table);
+
+  pivot_table_submit (table);
 }