subcase: Rename subcase_destroy() to subcase_uninit().
[pspp] / src / language / stats / median.c
index 49a4bc12e8bd6042efc38794761d1a88d0954386..c15108896ba575ca508a4dd14dc62089f668d5cb 100644 (file)
 #include "libpspp/str.h"
 #include "libpspp/misc.h"
 
-#include "output/tab.h"
+#include "output/pivot-table.h"
 
 #include "gettext.h"
+#define N_(msgid) msgid
 #define _(msgid) gettext (msgid)
 
 
@@ -117,7 +118,7 @@ median_execute (const struct dataset *ds,
   const bool n_sample_test = (value_compare_3way (&nst->val2, &nst->val1,
                                       var_get_width (nst->indep_var)) > 0);
 
-  struct results *results = xcalloc (nst->n_vars, sizeof (*results));
+  struct results *results = XCALLOC (nst->n_vars,  struct results);
   int n_vals = 0;
   for (v = 0; v < nst->n_vars; ++v)
     {
@@ -133,7 +134,7 @@ median_execute (const struct dataset *ds,
 
       if (n_sample_test == false)
        {
-         struct val_node *vn = xzalloc (sizeof *vn);
+         struct val_node *vn = XZALLOC (struct val_node);
          value_clone (&vn->val,  &nst->val1, var_get_width (nst->indep_var));
          hmap_insert (&map, &vn->node, value_hash (&nst->val1,
                                            var_get_width (nst->indep_var), 0));
@@ -144,7 +145,7 @@ median_execute (const struct dataset *ds,
                                            var_get_width (nst->indep_var), 0));
        }
 
-      if ( median == SYSMIS)
+      if (median == SYSMIS)
        {
          struct percentile *ptl;
          struct order_stats *os;
@@ -156,9 +157,9 @@ median_execute (const struct dataset *ds,
          rr = casereader_clone (r);
          writer = sort_create_writer (&sc, casereader_get_proto (rr));
 
-         for (; (c = casereader_read (rr)) != NULL; )
+         for (; (c = casereader_read (rr)) != NULL;)
            {
-             if ( var_is_value_missing (var, case_data (c, var), exclude))
+             if (var_is_value_missing (var, case_data (c, var)) & exclude)
                {
                  case_unref (c);
                  continue;
@@ -167,7 +168,7 @@ median_execute (const struct dataset *ds,
              cc += dict_get_case_weight (dict, c, &warn);
              casewriter_write (writer, c);
            }
-         subcase_destroy (&sc);
+         subcase_uninit (&sc);
          casereader_destroy (rr);
 
          rr = casewriter_make_reader (writer);
@@ -195,7 +196,7 @@ median_execute (const struct dataset *ds,
          const union value *val = case_data (c, var);
          const union value *indep_val = case_data (c, nst->indep_var);
 
-         if ( var_is_value_missing (var, case_data (c, var), exclude))
+         if (var_is_value_missing (var, case_data (c, var)) & exclude)
            {
              continue;
            }
@@ -208,16 +209,16 @@ median_execute (const struct dataset *ds,
                  value_compare_3way (indep_val, &nst->val1, width) < 0
                ||
                  value_compare_3way (indep_val, &nst->val2, width) > 0
-                  )
+               )
                {
                  continue;
                }
            }
 
          vn = find_value (&map, indep_val, nst->indep_var);
-         if ( vn == NULL)
+         if (vn == NULL)
            {
-             if ( n_sample_test == true)
+             if (n_sample_test == true)
                {
                  int width = var_get_width (nst->indep_var);
                  vn = xzalloc (sizeof *vn);
@@ -252,7 +253,7 @@ median_execute (const struct dataset *ds,
          }
 
        results[v].n = count;
-       results[v].sorted_array = xcalloc (hmap_count (&map), sizeof (void*));
+       results[v].sorted_array = XCALLOC (hmap_count (&map), struct val_node *);
        results[v].var = var;
 
        HMAP_FOR_EACH (vn, struct val_node, node, &map)
@@ -301,159 +302,85 @@ median_execute (const struct dataset *ds,
 static void
 show_frequencies (const struct n_sample_test *nst, const struct results *results,  int n_vals, const struct dictionary *dict)
 {
-  const struct variable *weight = dict_get_weight (dict);
-  const struct fmt_spec *wfmt = weight ? var_get_print_format (weight) : &F_8_0;
-
-  int i;
-  int v;
-
-  const int row_headers = 2;
-  const int column_headers = 2;
-  const int nc = row_headers + n_vals;
-  const int nr = column_headers + nst->n_vars * 2;
-
-  struct tab_table *table = tab_create (nc, nr);
-  tab_set_format (table, RC_WEIGHT, wfmt);
-
-  tab_headers (table, row_headers, 0, column_headers, 0);
-
-  tab_title (table, _("Frequencies"));
-
-  /* Box around the table and vertical lines inside*/
-  tab_box (table, TAL_2, TAL_2, -1, TAL_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_joint_text (table,
-                 row_headers, 0, row_headers + n_vals - 1, 0,
-                 TAT_TITLE | TAB_CENTER, var_to_string (nst->indep_var));
-
-
-  tab_hline (table, TAL_1, row_headers, tab_nc (table) - 1, 1);
-
-
-  for (i = 0; i < n_vals; ++i)
-    {
-      const struct results *rs = results + 0;
-      struct string label;
-      ds_init_empty (&label);
-
-      var_append_value_name (nst->indep_var, &rs->sorted_array[i]->val,
-                           &label);
-
-      tab_text (table, row_headers + i, 1,
-               TAT_TITLE | TAB_LEFT, ds_cstr (&label));
-
-      ds_destroy (&label);
-    }
-
-  for (v = 0; v < nst->n_vars; ++v)
+  struct pivot_table *table = pivot_table_create (N_("Frequencies"));
+  pivot_table_set_weight_var (table, dict_get_weight (dict));
+
+  struct pivot_dimension *indep = pivot_dimension_create__ (
+    table, PIVOT_AXIS_COLUMN, pivot_value_new_variable (nst->indep_var));
+  indep->root->show_label = true;
+  for (int i = 0; i < n_vals; ++i)
+    pivot_category_create_leaf_rc (
+      indep->root, pivot_value_new_var_value (
+        nst->indep_var, &results->sorted_array[i]->val), PIVOT_RC_COUNT);
+  pivot_dimension_create (table, PIVOT_AXIS_ROW, N_("Statistics"),
+                          N_("> Median"), N_("≤ Median"));
+
+  struct pivot_dimension *dep = pivot_dimension_create (
+    table, PIVOT_AXIS_ROW, N_("Dependent Variables"));
+
+  for (int v = 0; v < nst->n_vars; ++v)
     {
       const struct results *rs = &results[v];
-      tab_text (table,  0, column_headers + v * 2,
-               TAT_TITLE | TAB_LEFT, var_to_string (rs->var) );
-
-      tab_text (table,  1, column_headers + v * 2,
-               TAT_TITLE | TAB_LEFT, _("> Median") );
-
-      tab_text (table,  1, column_headers + v * 2 + 1,
-               TAT_TITLE | TAB_LEFT, _("≤ Median") );
 
-      if ( v > 0)
-       tab_hline (table, TAL_1, 0, tab_nc (table) - 1, column_headers + v * 2);
-    }
-
-  for (v = 0; v < nst->n_vars; ++v)
-    {
-      int i;
-      const struct results *rs = &results[v];
+      int dep_idx = pivot_category_create_leaf (
+        dep->root, pivot_value_new_variable (rs->var));
 
-      for (i = 0; i < n_vals; ++i)
+      for (int indep_idx = 0; indep_idx < n_vals; indep_idx++)
        {
-         const struct val_node *vn = rs->sorted_array[i];
-         tab_double (table, row_headers + i, column_headers + v * 2,
-                     0, vn->gt, NULL, RC_WEIGHT);
-
-         tab_double (table, row_headers + i, column_headers + v * 2 + 1,
-                     0, vn->le, NULL, RC_WEIGHT);
+         const struct val_node *vn = rs->sorted_array[indep_idx];
+          pivot_table_put3 (table, indep_idx, 0, dep_idx,
+                            pivot_value_new_number (vn->gt));
+          pivot_table_put3 (table, indep_idx, 1, dep_idx,
+                            pivot_value_new_number (vn->le));
        }
     }
 
-  tab_submit (table);
+  pivot_table_submit (table);
 }
 
-
 static void
 show_test_statistics (const struct n_sample_test *nst,
                      const struct results *results,
                      int n_vals,
                      const struct dictionary *dict)
 {
-  const struct variable *weight = dict_get_weight (dict);
-  const struct fmt_spec *wfmt = weight ? var_get_print_format (weight) : &F_8_0;
-
-  int v;
-
-  const int row_headers = 1;
-  const int column_headers = 1;
-  const int nc = row_headers + 5;
-  const int nr = column_headers + nst->n_vars;
-
-  struct tab_table *table = tab_create (nc, nr);
-  tab_set_format (table, RC_WEIGHT, wfmt);
-
-  tab_headers (table, row_headers, 0, column_headers, 0);
-
-  tab_title (table, _("Test Statistics"));
-
+  struct pivot_table *table = pivot_table_create (N_("Test Statistics"));
+  pivot_table_set_weight_var (table, dict_get_weight (dict));
 
-  tab_box (table, TAL_2, TAL_2, -1, TAL_1,
-          0,  0, tab_nc (table) - 1, tab_nr (table) - 1 );
+  pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Statistics"),
+                          N_("N"), PIVOT_RC_COUNT,
+                          N_("Median"),
+                          N_("Chi-Square"), PIVOT_RC_OTHER,
+                          N_("df"), PIVOT_RC_COUNT,
+                          N_("Asymp. Sig."), PIVOT_RC_SIGNIFICANCE);
 
-  tab_hline (table, TAL_2, 0, tab_nc (table) -1, column_headers);
-  tab_vline (table, TAL_2, row_headers, 0, tab_nr (table) - 1);
+  struct pivot_dimension *variables = pivot_dimension_create (
+    table, PIVOT_AXIS_ROW, N_("Variables"));
 
-  tab_text (table, row_headers + 0, 0,
-           TAT_TITLE | TAB_CENTER, _("N"));
-
-  tab_text (table, row_headers + 1, 0,
-           TAT_TITLE | TAB_CENTER, _("Median"));
-
-  tab_text (table, row_headers + 2, 0,
-           TAT_TITLE | TAB_CENTER, _("Chi-Square"));
-
-  tab_text (table, row_headers + 3, 0,
-           TAT_TITLE | TAB_CENTER, _("df"));
-
-  tab_text (table, row_headers + 4, 0,
-           TAT_TITLE | TAB_CENTER, _("Asymp. Sig."));
-
-
-  for (v = 0; v < nst->n_vars; ++v)
+  for (int v = 0; v < nst->n_vars; ++v)
     {
       double df = n_vals - 1;
       const struct results *rs = &results[v];
-      tab_text (table,  0, column_headers + v,
-               TAT_TITLE | TAB_LEFT, var_to_string (rs->var));
-
-
-      tab_double (table, row_headers + 0, column_headers + v,
-                 0, rs->n, NULL, RC_WEIGHT);
-
-      tab_double (table, row_headers + 1, column_headers + v,
-                 0, rs->median, NULL, RC_OTHER);
-
-      tab_double (table, row_headers + 2, column_headers + v,
-                 0, rs->chisq, NULL, RC_OTHER);
-
-      tab_double (table, row_headers + 3, column_headers + v,
-                 0, df, NULL, RC_WEIGHT);
 
-      tab_double (table, row_headers + 4, column_headers + v,
-                 0, gsl_cdf_chisq_Q (rs->chisq, df), NULL, RC_PVALUE);
+      int var_idx = pivot_category_create_leaf (
+        variables->root, pivot_value_new_variable (rs->var));
+
+      double entries[] = {
+        rs->n,
+        rs->median,
+        rs->chisq,
+        df,
+        gsl_cdf_chisq_Q (rs->chisq, df),
+      };
+      for (size_t i = 0; i < sizeof entries / sizeof *entries; i++)
+        {
+          struct pivot_value *value
+            = pivot_value_new_number (entries[i]);
+          if (i == 1)
+            value->numeric.format = *var_get_print_format (rs->var);
+          pivot_table_put2 (table, i, var_idx, value);
+        }
     }
 
-  tab_submit (table);
+  pivot_table_submit (table);
 }