#include "libpspp/i18n.h"
#include "libpspp/message.h"
#include "math/moments.h"
-#include "output/tab.h"
+#include "output/pivot-table.h"
#include "gl/xalloc.h"
struct dsc_trns
{
struct dsc_z_score *z_scores; /* Array of Z-scores. */
- int z_score_cnt; /* Number of Z-scores. */
+ int n_z_scores; /* Number of Z-scores. */
const struct variable **vars; /* Variables for listwise missing checks. */
- size_t var_cnt; /* Number of variables. */
+ size_t n_vars; /* Number of variables. */
enum dsc_missing_type missing_type; /* Treatment of missing values. */
enum mv_class exclude; /* Classes of missing values to exclude. */
- struct variable *filter; /* Dictionary FILTER BY variable. */
+ const struct variable *filter; /* Dictionary FILTER BY variable. */
struct casereader *z_reader; /* Reader for count, mean, stddev. */
casenumber count; /* Number left in this SPLIT FILE group.*/
bool ok;
double stats[DSC_N_STATS]; /* All the stats' values. */
};
-/* Output format. */
-enum dsc_format
- {
- DSC_LINE, /* Abbreviated format. */
- DSC_SERIAL /* Long format. */
- };
-
/* A DESCRIPTIVES procedure. */
struct dsc_proc
{
/* Per-variable info. */
+ struct dictionary *dict; /* Dictionary. */
struct dsc_var *vars; /* Variables. */
- size_t var_cnt; /* Number of variables. */
+ size_t n_vars; /* Number of variables. */
/* User options. */
enum dsc_missing_type missing_type; /* Treatment of missing values. */
enum mv_class exclude; /* Classes of missing values to exclude. */
- int show_var_labels; /* Nonzero to show variable labels. */
- int show_index; /* Nonzero to show variable index. */
- enum dsc_format format; /* Output format. */
/* Accumulated results. */
double missing_listwise; /* Sum of weights of cases missing listwise. */
struct dsc_proc *dsc, const char *name);
static char *generate_z_varname (const struct dictionary *dict,
struct dsc_proc *dsc,
- const char *name, int *z_cnt);
+ const char *name, int *n_zs);
static void dump_z_table (struct dsc_proc *);
static void setup_z_trns (struct dsc_proc *, struct dataset *);
struct dictionary *dict = dataset_dict (ds);
struct dsc_proc *dsc;
const struct variable **vars = NULL;
- size_t var_cnt = 0;
+ size_t n_vars = 0;
int save_z_scores = 0;
- int z_cnt = 0;
+ int n_zs = 0;
size_t i;
bool ok;
/* Create and initialize dsc. */
dsc = xmalloc (sizeof *dsc);
+ dsc->dict = dict;
dsc->vars = NULL;
- dsc->var_cnt = 0;
+ dsc->n_vars = 0;
dsc->missing_type = DSC_VARIABLE;
dsc->exclude = MV_ANY;
- dsc->show_var_labels = 1;
- dsc->show_index = 0;
- dsc->format = DSC_LINE;
dsc->missing_listwise = 0.;
dsc->valid = 0.;
dsc->bad_warn = 1;
lex_match (lexer, T_EQUALS);
while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH)
{
- if (lex_match_id (lexer, "LABELS"))
- dsc->show_var_labels = 1;
- else if (lex_match_id (lexer, "NOLABELS"))
- dsc->show_var_labels = 0;
- else if (lex_match_id (lexer, "INDEX"))
- dsc->show_index = 1;
- else if (lex_match_id (lexer, "NOINDEX"))
- dsc->show_index = 0;
- else if (lex_match_id (lexer, "LINE"))
- dsc->format = DSC_LINE;
- else if (lex_match_id (lexer, "SERIAL"))
- dsc->format = DSC_SERIAL;
+ if (lex_match_id (lexer, "LABELS")
+ || lex_match_id (lexer, "NOLABELS")
+ || lex_match_id (lexer, "INDEX")
+ || lex_match_id (lexer, "NOINDEX")
+ || lex_match_id (lexer, "LINE")
+ || lex_match_id (lexer, "SERIAL"))
+ {
+ /* Ignore. */
+ }
else
{
lex_error (lexer, NULL);
else
{
enum dsc_statistic s = match_statistic (lexer);
- if (s == DSC_NONE )
+ if (s == DSC_NONE)
{
lex_error (lexer, NULL);
goto error;
else
{
dsc->sort_by_stat = match_statistic (lexer);
- if (dsc->sort_by_stat == DSC_NONE )
+ if (dsc->sort_by_stat == DSC_NONE)
dsc->sort_by_stat = DSC_MEAN;
}
if (lex_match (lexer, T_LPAREN))
goto error;
}
}
- else if (var_cnt == 0)
+ else if (n_vars == 0)
{
if (lex_next_token (lexer, 1) == T_EQUALS)
{
{
int i;
- if (!parse_variables_const (lexer, dict, &vars, &var_cnt,
+ if (!parse_variables_const (lexer, dict, &vars, &n_vars,
PV_APPEND | PV_NO_DUPLICATE | PV_NUMERIC))
goto error;
- dsc->vars = xnrealloc ((void *)dsc->vars, var_cnt, sizeof *dsc->vars);
- for (i = dsc->var_cnt; i < var_cnt; i++)
+ dsc->vars = xnrealloc ((void *)dsc->vars, n_vars, sizeof *dsc->vars);
+ for (i = dsc->n_vars; i < n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
dv->v = vars[i];
dv->z_name = NULL;
dv->moments = NULL;
}
- dsc->var_cnt = var_cnt;
+ dsc->n_vars = n_vars;
if (lex_match (lexer, T_LPAREN))
{
}
if (try_name (dict, dsc, lex_tokcstr (lexer)))
{
- struct dsc_var *dsc_var = &dsc->vars[dsc->var_cnt - 1];
+ struct dsc_var *dsc_var = &dsc->vars[dsc->n_vars - 1];
dsc_var->z_name = xstrdup (lex_tokcstr (lexer));
- z_cnt++;
+ n_zs++;
}
else
msg (SE, _("Z-score variable name %s would be"
lex_match (lexer, T_SLASH);
}
- if (var_cnt == 0)
+ if (n_vars == 0)
{
msg (SE, _("No variables specified."));
goto error;
}
/* Construct z-score varnames, show translation table. */
- if (z_cnt || save_z_scores)
+ if (n_zs || save_z_scores)
{
struct caseproto *proto;
if (save_z_scores)
{
- int gen_cnt = 0;
+ int n_gens = 0;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dsc_var = &dsc->vars[i];
if (dsc_var->z_name == NULL)
{
const char *name = var_get_name (dsc_var->v);
dsc_var->z_name = generate_z_varname (dict, dsc, name,
- &gen_cnt);
+ &n_gens);
if (dsc_var->z_name == NULL)
goto error;
- z_cnt++;
+ n_zs++;
}
}
}
"Temporary transformations will be made permanent."));
proto = caseproto_create ();
- for (i = 0; i < 1 + 2 * z_cnt; i++)
+ for (i = 0; i < 1 + 2 * n_zs; i++)
proto = caseproto_add_width (proto, 0);
dsc->z_writer = autopaging_writer_create (proto);
caseproto_unref (proto);
/* Figure out which statistics to calculate. */
dsc->calc_stats = dsc->show_stats;
- if (z_cnt > 0)
+ if (n_zs > 0)
dsc->calc_stats |= (1ul << DSC_MEAN) | (1ul << DSC_STDDEV);
if (dsc->sort_by_stat >= 0)
dsc->calc_stats |= 1ul << dsc->sort_by_stat;
if (dsc->calc_stats & (1ul << i) && dsc_info[i].moment > dsc->max_moment)
dsc->max_moment = dsc_info[i].moment;
if (dsc->max_moment != MOMENT_NONE)
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
dsc->vars[i].moments = moments_create (dsc->max_moment);
/* Data pass. */
ok = proc_commit (ds) && ok;
/* Z-scoring! */
- if (ok && z_cnt)
+ if (ok && n_zs)
setup_z_trns (dsc, ds);
/* Done. */
if (dsc == NULL)
return;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dsc_var = &dsc->vars[i];
free (dsc_var->z_name);
if (dict_lookup_var (dict, name) != NULL)
return false;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dsc_var = &dsc->vars[i];
if (dsc_var->z_name != NULL && !utf8_strcasecmp (dsc_var->z_name, name))
as a dynamically allocated string. On failure, returns NULL. */
static char *
generate_z_varname (const struct dictionary *dict, struct dsc_proc *dsc,
- const char *var_name, int *z_cnt)
+ const char *var_name, int *n_zs)
{
char *z_name, *trunc_name;
/* Generate a synthetic name. */
for (;;)
{
- char name[8];
-
- (*z_cnt)++;
-
- if (*z_cnt <= 99)
- sprintf (name, "ZSC%03d", *z_cnt);
- else if (*z_cnt <= 108)
- sprintf (name, "STDZ%02d", *z_cnt - 99);
- else if (*z_cnt <= 117)
- sprintf (name, "ZZZZ%02d", *z_cnt - 108);
- else if (*z_cnt <= 126)
- sprintf (name, "ZQZQ%02d", *z_cnt - 117);
+ char name[16];
+
+ (*n_zs)++;
+
+ if (*n_zs <= 99)
+ sprintf (name, "ZSC%03d", *n_zs);
+ else if (*n_zs <= 108)
+ sprintf (name, "STDZ%02d", *n_zs - 99);
+ else if (*n_zs <= 117)
+ sprintf (name, "ZZZZ%02d", *n_zs - 108);
+ else if (*n_zs <= 126)
+ sprintf (name, "ZQZQ%02d", *n_zs - 117);
else
{
msg (SE, _("Ran out of generic names for Z-score variables. "
static void
dump_z_table (struct dsc_proc *dsc)
{
- size_t cnt = 0;
- struct tab_table *t;
-
- {
- size_t i;
+ struct pivot_table *table = pivot_table_create (
+ N_("Mapping of Variables to Z-scores"));
- for (i = 0; i < dsc->var_cnt; i++)
- if (dsc->vars[i].z_name != NULL)
- cnt++;
- }
+ pivot_dimension_create (table, PIVOT_AXIS_COLUMN, N_("Names"),
+ N_("Source"), N_("Target"));
- t = tab_create (2, cnt + 1);
- tab_title (t, _("Mapping of variables to corresponding Z-scores."));
- tab_headers (t, 0, 0, 1, 0);
- tab_box (t, TAL_1, TAL_1, TAL_0, TAL_1, 0, 0, 1, cnt);
- tab_hline (t, TAL_2, 0, 1, 1);
- tab_text (t, 0, 0, TAB_CENTER | TAT_TITLE, _("Source"));
- tab_text (t, 1, 0, TAB_CENTER | TAT_TITLE, _("Target"));
+ struct pivot_dimension *names = pivot_dimension_create (
+ table, PIVOT_AXIS_ROW, N_("Variables"));
+ names->hide_all_labels = true;
- {
- size_t i, y;
+ for (size_t i = 0; i < dsc->n_vars; i++)
+ if (dsc->vars[i].z_name != NULL)
+ {
+ int row = pivot_category_create_leaf (names->root,
+ pivot_value_new_number (i));
- for (i = 0, y = 1; i < dsc->var_cnt; i++)
- if (dsc->vars[i].z_name != NULL)
- {
- tab_text (t, 0, y, TAB_LEFT, var_to_string (dsc->vars[i].v));
- tab_text (t, 1, y++, TAB_LEFT, dsc->vars[i].z_name);
- }
- }
+ pivot_table_put2 (table, 0, row,
+ pivot_value_new_variable (dsc->vars[i].v));
+ pivot_table_put2 (table, 1, row,
+ pivot_value_new_user_text (dsc->vars[i].z_name, -1));
+ }
- tab_submit (t);
+ pivot_table_submit (table);
}
static void
{
const struct dsc_z_score *z;
- for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
- case_data_rw (c, z->z_var)->f = SYSMIS;
+ for (z = t->z_scores; z < t->z_scores + t->n_z_scores; z++)
+ *case_num_rw (c, z->z_var) = SYSMIS;
}
/* Transformation function to calculate Z-scores. Will return SYSMIS if any of
analyis. 4) any of the variables in the original analysis were missing
(either system or user-missing values that weren't included).
*/
-static int
+static enum trns_result
descriptives_trns_proc (void *trns_, struct ccase **c,
casenumber case_idx UNUSED)
{
if (t->filter)
{
double f = case_num (*c, t->filter);
- if (f == 0.0 || var_is_num_missing (t->filter, f, MV_ANY))
+ if (f == 0.0 || var_is_num_missing (t->filter, f))
{
descriptives_set_all_sysmis_zscores (t, *c);
return TRNS_CONTINUE;
size_t z_idx = 0;
t->count = case_num_idx (z_case, z_idx++);
- for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
+ for (z = t->z_scores; z < t->z_scores + t->n_z_scores; z++)
{
z->mean = case_num_idx (z_case, z_idx++);
z->std_dev = case_num_idx (z_case, z_idx++);
{
if (t->ok)
{
- msg (SE, _("Internal error processing Z scores"));
+ msg (SE, _("Internal error processing Z scores. "
+ "Please report this to %s."),
+ PACKAGE_BUGREPORT);
t->ok = false;
}
descriptives_set_all_sysmis_zscores (t, *c);
if (t->missing_type == DSC_LISTWISE)
{
assert(t->vars);
- for (vars = t->vars; vars < t->vars + t->var_cnt; vars++)
+ for (vars = t->vars; vars < t->vars + t->n_vars; vars++)
{
double score = case_num (*c, *vars);
- if (var_is_num_missing (*vars, score, t->exclude))
+ if (var_is_num_missing (*vars, score) & t->exclude)
{
descriptives_set_all_sysmis_zscores (t, *c);
return TRNS_CONTINUE;
}
}
- for (z = t->z_scores; z < t->z_scores + t->z_score_cnt; z++)
+ for (z = t->z_scores; z < t->z_scores + t->n_z_scores; z++)
{
double input = case_num (*c, z->src_var);
- double *output = &case_data_rw (*c, z->z_var)->f;
+ double *output = case_num_rw (*c, z->z_var);
if (z->mean == SYSMIS || z->std_dev == SYSMIS
- || var_is_num_missing (z->src_var, input, t->exclude))
+ || var_is_num_missing (z->src_var, input) & t->exclude)
*output = SYSMIS;
else
*output = (input - z->mean) / z->std_dev;
return ok;
}
+static const struct trns_class descriptives_trns_class = {
+ .name = "DESCRIPTIVES (Z scores)",
+ .execute = descriptives_trns_proc,
+ .destroy = descriptives_trns_free,
+};
+
/* Sets up a transformation to calculate Z scores. */
static void
setup_z_trns (struct dsc_proc *dsc, struct dataset *ds)
{
struct dsc_trns *t;
- size_t cnt, i;
+ size_t n, i;
- for (cnt = i = 0; i < dsc->var_cnt; i++)
+ for (n = i = 0; i < dsc->n_vars; i++)
if (dsc->vars[i].z_name != NULL)
- cnt++;
+ n++;
t = xmalloc (sizeof *t);
- t->z_scores = xnmalloc (cnt, sizeof *t->z_scores);
- t->z_score_cnt = cnt;
+ t->z_scores = xnmalloc (n, sizeof *t->z_scores);
+ t->n_z_scores = n;
t->missing_type = dsc->missing_type;
t->exclude = dsc->exclude;
- if ( t->missing_type == DSC_LISTWISE )
+ if (t->missing_type == DSC_LISTWISE)
{
- t->var_cnt = dsc->var_cnt;
- t->vars = xnmalloc (t->var_cnt, sizeof *t->vars);
- for (i = 0; i < t->var_cnt; i++)
+ t->n_vars = dsc->n_vars;
+ t->vars = xnmalloc (t->n_vars, sizeof *t->vars);
+ for (i = 0; i < t->n_vars; i++)
t->vars[i] = dsc->vars[i].v;
}
else
{
- t->var_cnt = 0;
+ t->n_vars = 0;
t->vars = NULL;
}
t->filter = dict_get_filter (dataset_dict (ds));
t->ok = true;
dsc->z_writer = NULL;
- for (cnt = i = 0; i < dsc->var_cnt; i++)
+ for (n = i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
if (dv->z_name != NULL)
var_set_label (dst_var, label);
free (label);
- z = &t->z_scores[cnt++];
+ z = &t->z_scores[n++];
z->src_var = dv->v;
z->z_var = dst_var;
}
}
- add_transformation (ds,
- descriptives_trns_proc, descriptives_trns_free, t);
+ add_transformation (ds, &descriptives_trns_class, t);
}
\f
/* Statistical calculation. */
calc_descriptives (struct dsc_proc *dsc, struct casereader *group,
struct dataset *ds)
{
- struct variable *filter = dict_get_filter (dataset_dict (ds));
+ const struct variable *filter = dict_get_filter (dataset_dict (ds));
struct casereader *pass1, *pass2;
casenumber count;
struct ccase *c;
pass1 = group;
pass2 = dsc->max_moment <= MOMENT_MEAN ? NULL : casereader_clone (pass1);
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
if (filter)
{
double f = case_num (c, filter);
- if (f == 0.0 || var_is_num_missing (filter, f, MV_ANY))
+ if (f == 0.0 || var_is_num_missing (filter, f))
continue;
}
}
dsc->valid += weight;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
double x = case_num (c, dv->v);
- if (var_is_num_missing (dv->v, x, dsc->exclude))
+ if (var_is_num_missing (dv->v, x) & dsc->exclude)
{
dv->missing += weight;
continue;
if (filter)
{
double f = case_num (c, filter);
- if (f == 0.0 || var_is_num_missing (filter, f, MV_ANY))
+ if (f == 0.0 || var_is_num_missing (filter, f))
continue;
}
if (dsc->missing_type == DSC_LISTWISE && listwise_missing (dsc, c))
continue;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
double x = case_num (c, dv->v);
- if (var_is_num_missing (dv->v, x, dsc->exclude))
+ if (var_is_num_missing (dv->v, x) & dsc->exclude)
continue;
if (dv->moments != NULL)
{
c = case_create (casewriter_get_proto (dsc->z_writer));
z_idx = 0;
- case_data_rw_idx (c, z_idx++)->f = count;
+ *case_num_rw_idx (c, z_idx++) = count;
}
else
c = NULL;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
double W;
if (dv->z_name && c != NULL)
{
- case_data_rw_idx (c, z_idx++)->f = dv->stats[DSC_MEAN];
- case_data_rw_idx (c, z_idx++)->f = dv->stats[DSC_STDDEV];
+ *case_num_rw_idx (c, z_idx++) = dv->stats[DSC_MEAN];
+ *case_num_rw_idx (c, z_idx++) = dv->stats[DSC_STDDEV];
}
}
{
size_t i;
- for (i = 0; i < dsc->var_cnt; i++)
+ for (i = 0; i < dsc->n_vars; i++)
{
struct dsc_var *dv = &dsc->vars[i];
double x = case_num (c, dv->v);
- if (var_is_num_missing (dv->v, x, dsc->exclude))
+ if (var_is_num_missing (dv->v, x) & dsc->exclude)
return true;
}
return false;
static void
display (struct dsc_proc *dsc)
{
- size_t i;
- int nc;
- struct tab_table *t;
-
- nc = 1 + (dsc->format == DSC_SERIAL ? 2 : 1);
- for (i = 0; i < DSC_N_STATS; i++)
+ struct pivot_table *table = pivot_table_create (
+ N_("Descriptive Statistics"));
+ pivot_table_set_weight_var (table, dict_get_weight (dsc->dict));
+
+ struct pivot_dimension *statistics = pivot_dimension_create (
+ table, PIVOT_AXIS_COLUMN, N_("Statistics"));
+ pivot_category_create_leaf_rc (
+ statistics->root, pivot_value_new_text (N_("N")), PIVOT_RC_COUNT);
+ for (int i = 0; i < DSC_N_STATS; i++)
if (dsc->show_stats & (1ul << i))
- nc++;
+ pivot_category_create_leaf (statistics->root,
+ pivot_value_new_text (dsc_info[i].name));
if (dsc->sort_by_stat != DSC_NONE)
- sort (dsc->vars, dsc->var_cnt, sizeof *dsc->vars,
+ sort (dsc->vars, dsc->n_vars, sizeof *dsc->vars,
descriptives_compare_dsc_vars, dsc);
- t = tab_create (nc, dsc->var_cnt + 1);
- tab_headers (t, 1, 0, 1, 0);
- tab_box (t, TAL_1, TAL_1, -1, -1, 0, 0, nc - 1, dsc->var_cnt);
- tab_box (t, -1, -1, -1, TAL_1, 1, 0, nc - 1, dsc->var_cnt);
- tab_hline (t, TAL_2, 0, nc - 1, 1);
- tab_vline (t, TAL_2, 1, 0, dsc->var_cnt);
-
- nc = 0;
- tab_text (t, nc++, 0, TAB_LEFT | TAT_TITLE, _("Variable"));
- if (dsc->format == DSC_SERIAL)
+ struct pivot_dimension *variables = pivot_dimension_create (
+ table, PIVOT_AXIS_ROW, N_("Variable"));
+ for (size_t i = 0; i < dsc->n_vars; i++)
{
- tab_text (t, nc++, 0, TAB_CENTER | TAT_TITLE, _("Valid N"));
- tab_text (t, nc++, 0, TAB_CENTER | TAT_TITLE, _("Missing N"));
- }
- else
- tab_text (t, nc++, 0, TAB_CENTER | TAT_TITLE, "N");
+ const struct dsc_var *dv = &dsc->vars[i];
- for (i = 0; i < DSC_N_STATS; i++)
- if (dsc->show_stats & (1ul << i))
- {
- const char *title = gettext (dsc_info[i].name);
- tab_text (t, nc++, 0, TAB_CENTER | TAT_TITLE, title);
- }
+ int row = pivot_category_create_leaf (variables->root,
+ pivot_value_new_variable (dv->v));
- for (i = 0; i < dsc->var_cnt; i++)
- {
- struct dsc_var *dv = &dsc->vars[i];
- size_t j;
+ int column = 0;
+ pivot_table_put2 (table, column++, row,
+ pivot_value_new_number (dv->valid));
- nc = 0;
- tab_text (t, nc++, i + 1, TAB_LEFT, var_to_string (dv->v));
- tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->valid);
- if (dsc->format == DSC_SERIAL)
- tab_text_format (t, nc++, i + 1, 0, "%.*g", DBL_DIG + 1, dv->missing);
-
- for (j = 0; j < DSC_N_STATS; j++)
+ for (int j = 0; j < DSC_N_STATS; j++)
if (dsc->show_stats & (1ul << j))
- tab_double (t, nc++, i + 1, TAB_NONE, dv->stats[j], NULL, RC_OTHER);
+ {
+ union value v = { .f = dv->stats[j] };
+ struct pivot_value *pv = (j == DSC_MIN || j == DSC_MAX
+ ? pivot_value_new_var_value (dv->v, &v)
+ : pivot_value_new_number (dv->stats[j]));
+ pivot_table_put2 (table, column++, row, pv);
+ }
}
- tab_title (t, _("Valid cases = %.*g; cases with missing value(s) = %.*g."),
- DBL_DIG + 1, dsc->valid,
- DBL_DIG + 1, dsc->missing_listwise);
-
- tab_submit (t);
+ int row = pivot_category_create_leaves (
+ variables->root, N_("Valid N (listwise)"), N_("Missing N (listwise)"));
+ pivot_table_put2 (table, 0, row, pivot_value_new_number (dsc->valid));
+ pivot_table_put2 (table, 0, row + 1,
+ pivot_value_new_number (dsc->missing_listwise));
+ pivot_table_submit (table);
}
/* Compares `struct dsc_var's A and B according to the ordering