Improve MGET output table.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 12 Nov 2021 03:46:02 +0000 (19:46 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 12 Nov 2021 03:46:02 +0000 (19:46 -0800)
src/language/stats/matrix.c
src/output/pivot-table.c
src/output/pivot-table.h

index 17b66de22ede53192e1bcb74e504a982cc2845c6..8eb029b7bae64ac95e348849fb45cbe81fda81cd 100644 (file)
@@ -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);
     }
 }
index f1e0e73372177d1ed566c690523f7b0e1b7bf0dc..6ba4c16f2e0811545b4b5673678900f5b37a1cf3 100644 (file)
@@ -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;
index eb7832542859d7f86b415822ef52e529f6ec1efb..e7e5ad403b1b38b0cb769e404b8f1c002b131212 100644 (file)
@@ -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 *);