From 22e7c4db280afc956a2059f228040bf6e1b01fce Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 31 Dec 2021 12:09:27 -0800 Subject: [PATCH] track axes --- src/language/stats/ctables.c | 50 +++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 7023c05adb..30ce9db8ab 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -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'); } -- 2.30.2