Sorting categories by explicit values.
authorBen Pfaff <blp@cs.stanford.edu>
Sun, 2 Jan 2022 22:40:49 +0000 (14:40 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 2 Apr 2022 01:48:55 +0000 (18:48 -0700)
src/language/stats/ctables.c

index 07de68d919361ecb73cd7c8b269b1698b21295f7..8277a702b28a165150f1191c0795aa763b1b761c 100644 (file)
@@ -388,6 +388,10 @@ struct ctables_cat_value
       };
   };
 
+static const struct ctables_cat_value *ctables_categories_match (
+  const struct ctables_categories *, const union value *,
+  const struct variable *);
+
 static void
 ctables_cat_value_uninit (struct ctables_cat_value *cv)
 {
@@ -1902,11 +1906,25 @@ ctables_freq_compare_3way (const void *a_, const void *b_, const void *aux_)
   for (size_t i = 0; i < va->n; i++)
     if (i != va->scale_idx)
       {
-        int cmp = value_compare_3way (&a->axes[aux->a].values[i],
-                                      &b->axes[aux->a].values[i],
-                                      var_get_width (va->vars[i]));
-        if (cmp)
-          return cmp;
+        const struct variable *var = va->vars[i];
+        const union value *val_a = &a->axes[aux->a].values[i];
+        const union value *val_b = &b->axes[aux->a].values[i];
+        int cmp = value_compare_3way (val_a, val_b, var_get_width (var));
+        if (!cmp)
+          continue;
+
+        const struct ctables_categories *cats = aux->t->categories[var_get_dict_index (var)];
+        if (cats && cats->n_values)
+          {
+            const struct ctables_cat_value *a_cv = ctables_categories_match (cats, val_a, var);
+            const struct ctables_cat_value *b_cv = ctables_categories_match (cats, val_b, var);
+            assert (a_cv && b_cv);
+            return (a_cv == b_cv ? cmp
+                    : a_cv > b_cv ? 1
+                    : -1);
+          }
+
+        return cmp;
       }
   return 0;
 }