From 68e2d49b47ccbe91c72c361641144a8938597e35 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 11 Nov 2021 19:46:02 -0800 Subject: [PATCH] Improve MGET output table. --- src/language/stats/matrix.c | 85 +++++++++++++++++++++++++++---------- src/output/pivot-table.c | 13 +++++- src/output/pivot-table.h | 2 + 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/src/language/stats/matrix.c b/src/language/stats/matrix.c index 17b66de22e..8eb029b7ba 100644 --- a/src/language/stats/matrix.c +++ b/src/language/stats/matrix.c @@ -4293,9 +4293,11 @@ matrix_cmd_execute_display (struct display_command *cmd) const struct matrix_state *s = cmd->state; struct pivot_table *table = pivot_table_create (N_("Matrix Variables")); - pivot_dimension_create ( - table, PIVOT_AXIS_COLUMN, N_("Property"), - N_("Rows"), N_("Columns"), N_("Size (kB)")); + struct pivot_dimension *attr_dimension + = pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Attribute")); + pivot_category_create_group (attr_dimension->root, N_("Dimension"), + N_("Rows"), N_("Columns")); + pivot_category_create_leaves (attr_dimension->root, N_("Size (kB)")); const struct matrix_var **vars = xmalloc (hmap_count (&s->vars) * sizeof *vars); size_t n_vars = 0; @@ -6257,7 +6259,9 @@ static void matrix_mget_commit_var (struct ccase **rows, size_t n_rows, const struct dictionary *d, const struct variable *rowtype_var, - struct matrix_state *s, size_t si, size_t fi, + struct matrix_state *s, + size_t ss, size_t sn, size_t si, + size_t fs, size_t fn, size_t fi, size_t cs, size_t cn, struct pivot_table *pt, struct pivot_dimension *var_dimension) @@ -6310,8 +6314,21 @@ matrix_mget_commit_var (struct ccase **rows, size_t n_rows, int var_index = pivot_category_create_leaf ( var_dimension->root, pivot_value_new_user_text (ds_cstr (&name), SIZE_MAX)); double values[] = { n_rows, cn }; + for (size_t j = 0; j < sn; j++) + { + struct variable *var = dict_get_var (d, ss + j); + pivot_table_put2 (pt, j, var_index, + pivot_value_new_number (case_num (rows[0], var))); + } + for (size_t j = 0; j < fn; j++) + { + struct variable *var = dict_get_var (d, fs + j); + pivot_table_put2 (pt, j + sn, var_index, + pivot_value_new_number (case_num (rows[0], var))); + } for (size_t j = 0; j < sizeof values / sizeof *values; j++) - pivot_table_put2 (pt, j, var_index, pivot_value_new_integer (values[j])); + pivot_table_put2 (pt, j + sn + fn, var_index, + pivot_value_new_integer (values[j])); if (n_missing) msg (SE, ngettext ("Matrix data file variable %s contains a missing " @@ -6353,9 +6370,7 @@ vars_changed (const struct ccase *ca, const struct ccase *cb, static void matrix_cmd_execute_mget__ (struct mget_command *mget, - struct casereader *r, const struct dictionary *d, - struct pivot_table *pt, - struct pivot_dimension *var_dimension) + struct casereader *r, const struct dictionary *d) { const struct variable *rowtype_ = get_a8_var (d, "ROWTYPE_"); const struct variable *varname_ = get_a8_var (d, "VARNAME_"); @@ -6402,6 +6417,32 @@ matrix_cmd_execute_mget__ (struct mget_command *mget, size_t cn = dict_get_var_cnt (d) - cs; struct ccase *cc = NULL; + /* Pivot table. */ + struct pivot_table *pt = pivot_table_create ( + N_("Matrix Variables Created by MGET")); + struct pivot_dimension *attr_dimension = pivot_dimension_create ( + pt, PIVOT_AXIS_COLUMN, N_("Attribute")); + struct pivot_dimension *var_dimension = pivot_dimension_create ( + pt, PIVOT_AXIS_ROW, N_("Variable")); + if (sn > 0) + { + struct pivot_category *splits = pivot_category_create_group ( + attr_dimension->root, N_("Split Values")); + for (size_t i = 0; i < sn; i++) + pivot_category_create_leaf (splits, pivot_value_new_variable ( + dict_get_var (d, ss + i))); + } + if (fn > 0) + { + struct pivot_category *factors = pivot_category_create_group ( + attr_dimension->root, N_("Factor Values")); + for (size_t i = 0; i < fn; i++) + pivot_category_create_leaf (factors, pivot_value_new_variable ( + dict_get_var (d, fs + i))); + } + pivot_category_create_group (attr_dimension->root, N_("Dimensions"), + N_("Rows"), N_("Columns")); + /* Matrix. */ struct ccase **rows = NULL; size_t allocated_rows = 0; @@ -6426,7 +6467,10 @@ matrix_cmd_execute_mget__ (struct mget_command *mget, if (change != NOTHING_CHANGED) { matrix_mget_commit_var (rows, n_rows, d, rowtype_, - mget->state, si, fi, cs, cn, + mget->state, + ss, sn, si, + fs, fn, fi, + cs, cn, pt, var_dimension); n_rows = 0; case_unref (cc); @@ -6459,13 +6503,21 @@ matrix_cmd_execute_mget__ (struct mget_command *mget, } } matrix_mget_commit_var (rows, n_rows, d, rowtype_, - mget->state, si, fi, cs, cn, + mget->state, + ss, sn, si, + fs, fn, fi, + cs, cn, pt, var_dimension); free (rows); case_unref (sc); case_unref (fc); case_unref (cc); + + if (var_dimension->n_leaves) + pivot_table_submit (pt); + else + pivot_table_unref (pt); } static void @@ -6476,18 +6528,7 @@ matrix_cmd_execute_mget (struct mget_command *mget) if (matrix_open_casereader ("MGET", mget->file, mget->encoding, mget->state->dataset, &r, &d)) { - struct pivot_table *pt = pivot_table_create ( - N_("Matrix Variables Created by MGET")); - pivot_dimension_create (pt, PIVOT_AXIS_COLUMN, N_("Dimension"), - N_("Rows"), N_("Columns")); - struct pivot_dimension *var_dimension = pivot_dimension_create ( - pt, PIVOT_AXIS_ROW, N_("Variable")); - matrix_cmd_execute_mget__ (mget, r, d, pt, var_dimension); - if (var_dimension->n_leaves) - pivot_table_submit (pt); - else - pivot_table_unref (pt); - + matrix_cmd_execute_mget__ (mget, r, d); matrix_close_casereader (mget->file, mget->state->dataset, r, d); } } diff --git a/src/output/pivot-table.c b/src/output/pivot-table.c index f1e0e73372..6ba4c16f2e 100644 --- a/src/output/pivot-table.c +++ b/src/output/pivot-table.c @@ -2844,13 +2844,22 @@ pivot_value_new_value (const union value *value, int width, /* Returns a new pivot_value for VARIABLE. */ struct pivot_value * pivot_value_new_variable (const struct variable *variable) +{ + return pivot_value_new_variable__ (var_get_name (variable), + var_get_label (variable)); +} + +/* Returns a new pivot_value for a variable with the given NAME and optional + LABEL. */ +struct pivot_value * +pivot_value_new_variable__ (const char *name, const char *label) { struct pivot_value *value = xmalloc (sizeof *value); *value = (struct pivot_value) { .variable = { .type = PIVOT_VALUE_VARIABLE, - .var_name = xstrdup (var_get_name (variable)), - .var_label = xstrdup_if_nonempty (var_get_label (variable)), + .var_name = xstrdup (name), + .var_label = xstrdup_if_nonempty (label), }, }; return value; diff --git a/src/output/pivot-table.h b/src/output/pivot-table.h index eb78325428..e7e5ad403b 100644 --- a/src/output/pivot-table.h +++ b/src/output/pivot-table.h @@ -739,6 +739,8 @@ struct pivot_value *pivot_value_new_value (const union value *, int width, /* Values from variable names. */ struct pivot_value *pivot_value_new_variable (const struct variable *); +struct pivot_value *pivot_value_new_variable__ (const char *name, + const char *label); /* Values from text strings. */ struct pivot_value *pivot_value_new_text (const char *); -- 2.30.2