work on adding empty categories
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 31 Jan 2022 06:10:55 +0000 (22:10 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 2 Apr 2022 01:48:55 +0000 (18:48 -0700)
src/language/stats/ctables.c

index d6b5a0ca0c119c9764e49377d65a286466f5dcf8..12846d0c4180fce4be452d2de8ef1b8d72175520 100644 (file)
@@ -3312,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;