track axes
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 31 Dec 2021 20:09:27 +0000 (12:09 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 13 Jan 2022 05:52:27 +0000 (21:52 -0800)
src/language/stats/ctables.c

index 7023c05adbedaf01e8ae62c8ad13041edebd3340..30ce9db8ab010cbee13227a983516d8779ad1752 100644 (file)
@@ -1245,6 +1245,7 @@ struct var_array
   {
     const struct ctables_axis *summary;
     struct variable **vars;
+    enum pivot_axis_type *axes;
     size_t n;
   };
 
@@ -1252,7 +1253,10 @@ static void
 var_array_uninit (struct var_array *va)
 {
   if (va)
-    free (va->vars);
+    {
+      free (va->vars);
+      free (va->axes);
+    }
 }
 
 struct var_array2
@@ -1289,17 +1293,27 @@ nest_fts (struct var_array2 va0, struct var_array2 va1)
 
         size_t allocate = a->n + b->n;
         struct variable **vars = xnmalloc (allocate, sizeof *vars);
+        enum pivot_axis_type *axes = xnmalloc (allocate, sizeof *axes);
         size_t n = 0;
         for (size_t k = 0; k < a->n; k++)
-          vars[n++] = a->vars[k];
+          {
+            vars[n] = a->vars[k];
+            axes[n] = a->axes[k];
+            n++;
+          }
         for (size_t k = 0; k < b->n; k++)
-          vars[n++] = b->vars[k];
+          {
+            vars[n] = b->vars[k];
+            axes[n] = b->axes[k];
+            n++;
+          }
         assert (n == allocate);
 
         assert (!(a->summary && b->summary));
         vaa.vas[vaa.n++] = (struct var_array) {
           .summary = a->summary ? a->summary : b->summary,
           .vars = vars,
+          .axes = axes,
           .n = n
         };
       }
@@ -1323,7 +1337,7 @@ stack_fts (struct var_array2 va0, struct var_array2 va1)
 }
 
 static struct var_array2
-enumerate_fts (const struct ctables_axis *a)
+enumerate_fts (enum pivot_axis_type axis_type, const struct ctables_axis *a)
 {
   if (!a)
     return (struct var_array2) { .n = 0 };
@@ -1337,20 +1351,22 @@ enumerate_fts (const struct ctables_axis *a)
         *va = (struct var_array) { .n = 0 };
       else
         {
-          struct variable **v = xmalloc (sizeof *v);
-          *v = a->var.var;
-          *va = (struct var_array) { .vars = v, .n = 1 };
+          struct variable **vars = xmalloc (sizeof *vars);
+          *vars = a->var.var;
+          enum pivot_axis_type *axes = xmalloc (sizeof *axes);
+          *axes = axis_type;
+          *va = (struct var_array) { .vars = vars, .axes = axes, .n = 1 };
         }
       va->summary = a->scale || a->n_summaries ? a : NULL;
       return (struct var_array2) { .vas = va, .n = 1 };
 
     case CTAO_STACK:
-      return stack_fts (enumerate_fts (a->subs[0]),
-                        enumerate_fts (a->subs[1]));
+      return stack_fts (enumerate_fts (axis_type, a->subs[0]),
+                        enumerate_fts (axis_type, a->subs[1]));
 
     case CTAO_NEST:
-      return nest_fts (enumerate_fts (a->subs[0]),
-                       enumerate_fts (a->subs[1]));
+      return nest_fts (enumerate_fts (axis_type, a->subs[0]),
+                       enumerate_fts (axis_type, a->subs[1]));
     }
 
   NOT_REACHED ();
@@ -1846,16 +1862,20 @@ ctables_execute (struct dataset *ds, struct ctables *ct)
       size_t allocated_fts = 0;
 
       struct ctables_table *t = &ct->tables[i];
-      struct var_array2 vaa = enumerate_fts (t->axes[PIVOT_AXIS_ROW]);
-      vaa = nest_fts (vaa, enumerate_fts (t->axes[PIVOT_AXIS_COLUMN]));
-      vaa = nest_fts (vaa, enumerate_fts (t->axes[PIVOT_AXIS_LAYER]));
+      struct var_array2 vaa = { .n = 0 };
+      for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
+        vaa = nest_fts (vaa, enumerate_fts (a, t->axes[a]));
       for (size_t i = 0; i < vaa.n; i++)
         {
           for (size_t j = 0; j < vaa.vas[i].n; j++)
             {
               if (j)
                 fputs (", ", stdout);
-              fputs (var_get_name (vaa.vas[i].vars[j]), stdout);
+              printf ("%s (%c)", var_get_name (vaa.vas[i].vars[j]),
+                      vaa.vas[i].axes[j] == PIVOT_AXIS_ROW ? 'r'
+                      : vaa.vas[i].axes[j] == PIVOT_AXIS_COLUMN ? 'c'
+                      : vaa.vas[i].axes[j] == PIVOT_AXIS_LAYER ? 'l'
+                      : '?');
             }
           putchar ('\n');
         }