- struct tab_table *t;
- int nc, nr, heading_columns, currow;
- int i, j;
- nc = qc->ngroups + 1;
- nr = qc->n_vars + 4;
- heading_columns = 1;
- t = tab_create (nc, nr);
- tab_headers (t, 0, nc - 1, 0, 1);
- currow = 0;
- if (!initial)
- {
- tab_title (t, _("Final Cluster Centers"));
- }
- else
- {
- tab_title (t, _("Initial Cluster Centers"));
- }
- tab_box (t, TAL_2, TAL_2, TAL_0, TAL_1, 0, 0, nc - 1, nr - 1);
- tab_joint_text (t, 1, 0, nc - 1, 0, TAB_CENTER, _("Cluster"));
- tab_hline (t, TAL_1, 1, nc - 1, 2);
- currow += 2;
+ struct pivot_table *table
+ = pivot_table_create (initial
+ ? N_("Initial Cluster Centers")
+ : N_("Final Cluster Centers"));
+
+ struct pivot_dimension *clusters
+ = pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Cluster"));
+
+ clusters->root->show_label = true;
+ for (size_t i = 0; i < qc->ngroups; i++)
+ pivot_category_create_leaf (clusters->root,
+ pivot_value_new_integer (i + 1));
+
+ struct pivot_dimension *variables
+ = pivot_dimension_create (table, PIVOT_AXIS_ROW, N_("Variable"));
+
+ for (size_t i = 0; i < qc->n_vars; i++)
+ pivot_category_create_leaf (variables->root,
+ pivot_value_new_variable (qc->vars[i]));
+
+ const gsl_matrix *matrix = (initial
+ ? kmeans->initial_centers
+ : kmeans->centers);
+ for (size_t i = 0; i < qc->ngroups; i++)
+ for (size_t j = 0; j < qc->n_vars; j++)
+ {
+ double x = gsl_matrix_get (matrix, kmeans->group_order->data[i], j);
+ union value v = { .f = x };
+ pivot_table_put2 (table, i, j,
+ pivot_value_new_var_value (qc->vars[j], &v));
+ }
+
+ pivot_table_submit (table);
+}
+
+
+/* A transformation function which juxtaposes the dataset with the
+ (pre-prepared) dataset containing membership and/or distance
+ values. */
+static enum trns_result
+save_trans_func (void *aux, struct ccase **c, casenumber x UNUSED)
+{
+ const struct save_trans_data *std = aux;
+ struct ccase *ca = casereader_read (std->appending_reader);
+ if (ca == NULL)
+ return TRNS_CONTINUE;
+
+ *c = case_unshare (*c);
+
+ if (std->membership_case_idx >= 0)
+ *case_num_rw (*c, std->membership) = case_num_idx (ca, std->membership_case_idx);
+
+ if (std->distance_case_idx >= 0)
+ *case_num_rw (*c, std->distance) = case_num_idx (ca, std->distance_case_idx);
+
+ case_unref (ca);
+
+ return TRNS_CONTINUE;
+}
+
+/* Free the resources of the transformation. */
+static bool
+save_trans_destroy (void *aux)
+{
+ struct save_trans_data *std = aux;
+ casereader_destroy (std->appending_reader);
+ free (std);
+ return true;
+}