work on adding empty categories
[pspp] / src / language / stats / ctables.c
index 4a0787dd21e9f30d48f89dc12d1acc5af41face5..12846d0c4180fce4be452d2de8ef1b8d72175520 100644 (file)
@@ -2649,15 +2649,9 @@ recurse_subtotals (struct ctables_table *t, const struct ccase *c,
 static void
 ctables_cell_insert (struct ctables_table *t,
                      const struct ccase *c,
-                     size_t ir, size_t ic, size_t il,
+                     size_t ix[PIVOT_N_AXES],
                      double d_weight, double e_weight)
 {
-  size_t ix[PIVOT_N_AXES] = {
-    [PIVOT_AXIS_ROW] = ir,
-    [PIVOT_AXIS_COLUMN] = ic,
-    [PIVOT_AXIS_LAYER] = il,
-  };
-
   const struct ctables_category *cats[PIVOT_N_AXES][10];
   for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
     {
@@ -2924,6 +2918,8 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t)
               struct pivot_category *parent = k ? groups[k - 1] : d[a]->root;
               if (level->type == CTL_SUMMARY)
                 {
+                  assert (k == n_levels - 1);
+
                   const struct ctables_summary_spec_set *specs = &t->summary_specs;
                   for (size_t m = 0; m < specs->n; m++)
                     {
@@ -3316,9 +3312,53 @@ ctables_sort_clabels_values (struct ctables_table *t)
     t->clabels_values[i]->leaf = i;
 }
 
+static void
+add_empty_categories (struct ctables_table *t, const struct ccase *c,
+                      size_t ix[PIVOT_N_AXES],
+                      enum pivot_axis_type start_axis, size_t start_nest)
+{
+  for (enum pivot_axis_type a = start_axis; a < PIVOT_N_AXES; a++)
+    {
+      const struct ctables_nest *nest = &t->stacks[a].nests[ix[a]];
+      for (size_t i = start_nest; i < nest->n; i++)
+        {
+          if (i == nest->scale_idx)
+            continue;
+
+          const struct ctables_category *save = cats[a][i];
+          if (save->subtotal)
+            {
+              cats[a][i] = save->subtotal;
+              ctables_cell_add__ (t, c, ix, cats, d_weight, e_weight);
+              recurse_subtotals (t, c, ix, cats, d_weight, e_weight, a, i + 1);
+              cats[a][i] = save;
+            }
+        }
+      start_nest = 0;
+    }
+}
+
 static bool
 ctables_execute (struct dataset *ds, struct ctables *ct)
 {
+  for (size_t i = 0; i < ct->n_tables; i++)
+    {
+      struct ctables_table *t = ct->tables[i];
+
+      for (size_t ir = 0; ir < t->stacks[PIVOT_AXIS_ROW].n; ir++)
+        for (size_t ic = 0; ic < t->stacks[PIVOT_AXIS_COLUMN].n; ic++)
+          for (size_t il = 0; il < t->stacks[PIVOT_AXIS_LAYER].n; il++)
+            {
+              size_t ix[PIVOT_N_AXES] = {
+                [PIVOT_AXIS_ROW] = ir,
+                [PIVOT_AXIS_COLUMN] = ic,
+                [PIVOT_AXIS_LAYER] = il,
+              };
+
+              add_empty_categories (t, ix, 0, 0);
+            }
+    }
+
   struct casereader *input = proc_open (ds);
   bool warn_on_invalid = true;
   for (struct ccase *c = casereader_read (input); c;
@@ -3339,7 +3379,15 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
           for (size_t ir = 0; ir < t->stacks[PIVOT_AXIS_ROW].n; ir++)
             for (size_t ic = 0; ic < t->stacks[PIVOT_AXIS_COLUMN].n; ic++)
               for (size_t il = 0; il < t->stacks[PIVOT_AXIS_LAYER].n; il++)
-                ctables_cell_insert (t, c, ir, ic, il, d_weight, e_weight);
+                {
+                  size_t ix[PIVOT_N_AXES] = {
+                    [PIVOT_AXIS_ROW] = ir,
+                    [PIVOT_AXIS_COLUMN] = ic,
+                    [PIVOT_AXIS_LAYER] = il,
+                  };
+
+                  ctables_cell_insert (t, c, ix, d_weight, e_weight);
+                }
 
           for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
             if (t->label_axis[a] != a)