}
static bool
-is_rowtype (const union value *v, const char *rowtype)
+var_changed (const struct ccase *ca, const struct ccase *cb,
+ const struct variable *var)
{
- struct substring vs = ss_buffer (CHAR_CAST (char *, v->s), 8);
- ss_rtrim (&vs, ss_cstr (" "));
- return ss_equals_case (vs, ss_cstr (rowtype));
+ return (ca && cb
+ ? !value_equal (case_data (ca, var), case_data (cb, var),
+ var_get_width (var))
+ : ca || cb);
+}
+
+static bool
+vars_changed (const struct ccase *ca, const struct ccase *cb,
+ const struct dictionary *d,
+ size_t first_var, size_t n_vars)
+{
+ for (size_t i = 0; i < n_vars; i++)
+ {
+ const struct variable *v = dict_get_var (d, first_var + i);
+ if (var_changed (ca, cb, v))
+ return true;
+ }
+ return false;
+}
+
+static bool
+vars_all_missing (const struct ccase *c, const struct dictionary *d,
+ size_t first_var, size_t n_vars)
+{
+ for (size_t i = 0; i < n_vars; i++)
+ if (case_num (c, dict_get_var (d, first_var + i)) != SYSMIS)
+ return false;
+ return true;
}
static void
matrix_mget_commit_var (struct ccase **rows, size_t n_rows,
const struct dictionary *d,
const struct variable *rowtype_var,
+ const struct stringi_set *accepted_rowtypes,
struct matrix_state *s,
size_t ss, size_t sn, size_t si,
size_t fs, size_t fn, size_t fi,
struct pivot_dimension *var_dimension)
{
if (!n_rows)
- return;
+ goto exit;
+
+ /* Is this a matrix for pooled data, either where there are no factor
+ variables or the factor variables are missing? */
+ bool pooled = !fn || vars_all_missing (rows[0], d, fs, fn);
- const union value *rowtype_ = case_data (rows[0], rowtype_var);
- const char *name_prefix = (is_rowtype (rowtype_, "COV") ? "CV"
- : is_rowtype (rowtype_, "CORR") ? "CR"
- : is_rowtype (rowtype_, "MEAN") ? "MN"
- : is_rowtype (rowtype_, "STDDEV") ? "SD"
- : is_rowtype (rowtype_, "N") ? "NC"
- : "CN");
+ struct substring rowtype = case_ss (rows[0], rowtype_var);
+ ss_rtrim (&rowtype, ss_cstr (" "));
+ if (!stringi_set_is_empty (accepted_rowtypes)
+ && !stringi_set_contains_len (accepted_rowtypes,
+ rowtype.string, rowtype.length))
+ goto exit;
struct string name = DS_EMPTY_INITIALIZER;
- ds_put_cstr (&name, name_prefix);
- if (fi > 0)
+ ds_put_cstr (&name, (ss_equals_case (rowtype, ss_cstr ("COV")) ? "CV"
+ : ss_equals_case (rowtype, ss_cstr ("CORR")) ? "CR"
+ : ss_equals_case (rowtype, ss_cstr ("MEAN")) ? "MN"
+ : ss_equals_case (rowtype, ss_cstr ("STDDEV")) ? "SD"
+ : ss_equals_case (rowtype, ss_cstr ("N")) ? "NC"
+ : "CN"));
+ if (!pooled)
ds_put_format (&name, "F%zu", fi);
if (si > 0)
ds_put_format (&name, "S%zu", si);
{
msg (SW, _("Matrix data file contains variable with existing name %s."),
ds_cstr (&name));
- goto exit;
+ goto exit_free_name;
}
gsl_matrix *m = gsl_matrix_alloc (n_rows, cn);
for (size_t j = 0; j < fn; j++)
{
struct variable *var = dict_get_var (d, fs + j);
- const union value *value = case_data (rows[0], var);
+ const union value sysmis = { .f = SYSMIS };
+ const union value *value = pooled ? &sysmis : case_data (rows[0], var);
pivot_table_put2 (pt, j + sn, var_index,
pivot_value_new_var_value (var, value));
}
ds_cstr (&name), n_missing);
mv->value = m;
-exit:
+exit_free_name:
ds_destroy (&name);
+
+exit:
for (size_t y = 0; y < n_rows; y++)
case_unref (rows[y]);
}
-static bool
-var_changed (const struct ccase *ca, const struct ccase *cb,
- const struct variable *var)
-{
- return (ca && cb
- ? !value_equal (case_data (ca, var), case_data (cb, var),
- var_get_width (var))
- : ca || cb);
-}
-
-static bool
-vars_changed (const struct ccase *ca, const struct ccase *cb,
- const struct dictionary *d,
- size_t first_var, size_t n_vars)
-{
- for (size_t i = 0; i < n_vars; i++)
- {
- const struct variable *v = dict_get_var (d, first_var + i);
- if (var_changed (ca, cb, v))
- return true;
- }
- return false;
-}
-
static void
matrix_cmd_execute_mget__ (struct mget_command *mget,
struct casereader *r, const struct dictionary *d)
if (fn > 0)
{
struct pivot_category *factors = pivot_category_create_group (
- attr_dimension->root, N_("Factor Values"));
+ attr_dimension->root, N_("Factors"));
for (size_t i = 0; i < fn; i++)
pivot_category_create_leaf (factors, pivot_value_new_variable (
dict_get_var (d, fs + i)));
struct ccase *c;
while ((c = casereader_read (r)) != NULL)
{
+ bool row_has_factors = fn && !vars_all_missing (c, d, fs, fn);
+
enum
{
SPLITS_CHANGED,
if (change != NOTHING_CHANGED)
{
- matrix_mget_commit_var (rows, n_rows, d, rowtype_,
+ matrix_mget_commit_var (rows, n_rows, d,
+ rowtype_, &mget->rowtypes,
mget->state,
ss, sn, si,
fs, fn, fi,
/* Reset the factor number, if there are factors. */
if (fn)
{
- fi = 1;
+ fi = 0;
+ if (row_has_factors)
+ fi++;
case_unref (fc);
fc = case_ref (c);
}
}
else if (change == FACTORS_CHANGED)
{
- fi++;
+ if (row_has_factors)
+ fi++;
case_unref (fc);
fc = case_ref (c);
}
}
- matrix_mget_commit_var (rows, n_rows, d, rowtype_,
+ matrix_mget_commit_var (rows, n_rows, d,
+ rowtype_, &mget->rowtypes,
mget->state,
ss, sn, si,
fs, fn, fi,