X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fmeans.c;h=9a07a14bb6f3dcffac0d82bfc5c98c36df95a200;hb=fd308174a81b1702426720536acd3aa4a3021801;hp=5312ace3a5424e05fd447929806574ba34c47e07;hpb=c2dbc834863c3088991bc2f6f6e32c595e7f1079;p=pspp diff --git a/src/language/stats/means.c b/src/language/stats/means.c index 5312ace3a5..9a07a14bb6 100644 --- a/src/language/stats/means.c +++ b/src/language/stats/means.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2011, 2012 Free Software Foundation, Inc. + Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ #include - #include "data/case.h" #include "data/casegrouper.h" #include "data/casereader.h" @@ -54,12 +53,9 @@ struct per_var_data }; -typedef void *stat_create (const struct means *, struct pool *pool); - -typedef void stat_update (const struct means *, void *stat, double w, double x); - -typedef double stat_get (const struct means *, struct per_var_data *, void *aux); - +typedef void *stat_create (struct pool *pool); +typedef void stat_update (void *stat, double w, double x); +typedef double stat_get (const struct per_var_data *, void *aux); struct cell_spec { @@ -74,16 +70,14 @@ struct cell_spec stat_get *sd; }; - struct harmonic_mean { double rsum; double n; }; - static void * -harmonic_create (const struct means *means UNUSED, struct pool *pool) +harmonic_create (struct pool *pool) { struct harmonic_mean *hm = pool_alloc (pool, sizeof *hm); @@ -95,7 +89,7 @@ harmonic_create (const struct means *means UNUSED, struct pool *pool) static void -harmonic_update (const struct means *means UNUSED, void *stat, double w, double x) +harmonic_update (void *stat, double w, double x) { struct harmonic_mean *hm = stat; hm->rsum += w / x; @@ -104,7 +98,7 @@ harmonic_update (const struct means *means UNUSED, void *stat, double w, double static double -harmonic_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +harmonic_get (const struct per_var_data *pvd UNUSED, void *stat) { struct harmonic_mean *hm = stat; @@ -121,7 +115,7 @@ struct geometric_mean static void * -geometric_create (const struct means *means UNUSED, struct pool *pool) +geometric_create (struct pool *pool) { struct geometric_mean *gm = pool_alloc (pool, sizeof *gm); @@ -133,7 +127,7 @@ geometric_create (const struct means *means UNUSED, struct pool *pool) static void -geometric_update (const struct means *means UNUSED, void *stat, double w, double x) +geometric_update (void *stat, double w, double x) { struct geometric_mean *gm = stat; gm->prod *= pow (x, w); @@ -142,7 +136,7 @@ geometric_update (const struct means *means UNUSED, void *stat, double w, double static double -geometric_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +geometric_get (const struct per_var_data *pvd UNUSED, void *stat) { struct geometric_mean *gm = stat; @@ -151,14 +145,8 @@ geometric_get (const struct means *means UNUSED, struct per_var_data *pvd, void -static void * -sum_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - static double -sum_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +sum_get (const struct per_var_data *pvd, void *stat UNUSED) { double n, mean; @@ -168,14 +156,8 @@ sum_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) } -static void * -n_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - static double -n_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +n_get (const struct per_var_data *pvd, void *stat UNUSED) { double n; @@ -184,14 +166,8 @@ n_get (const struct means *means UNUSED, struct per_var_data *pvd, void *stat) return n; } -static void * -arithmean_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - static double -arithmean_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +arithmean_get (const struct per_var_data *pvd, void *stat UNUSED) { double n, mean; @@ -200,14 +176,8 @@ arithmean_get (const const struct means *means UNUSED, struct per_var_data *pvd, return mean; } -static void * -stddev_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - static double -variance_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +variance_get (const struct per_var_data *pvd, void *stat UNUSED) { double n, mean, variance; @@ -218,22 +188,16 @@ variance_get (const const struct means *means UNUSED, struct per_var_data *pvd, static double -stddev_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +stddev_get (const struct per_var_data *pvd, void *stat) { - return sqrt (variance_get (means, pvd, stat)); + return sqrt (variance_get (pvd, stat)); } -static void * -skew_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - static double -skew_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +skew_get (const struct per_var_data *pvd, void *stat UNUSED) { double skew; @@ -243,7 +207,7 @@ skew_get (const const struct means *means UNUSED, struct per_var_data *pvd, void } static double -sekurt_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +sekurt_get (const struct per_var_data *pvd, void *stat UNUSED) { double n; @@ -252,10 +216,8 @@ sekurt_get (const const struct means *means UNUSED, struct per_var_data *pvd, vo return calc_sekurt (n); } - - static double -seskew_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +seskew_get (const struct per_var_data *pvd, void *stat UNUSED) { double n; @@ -264,17 +226,8 @@ seskew_get (const const struct means *means UNUSED, struct per_var_data *pvd, vo return calc_seskew (n); } - - -static void * -kurt_create (const struct means *means UNUSED, struct pool *pool) -{ - return NULL; -} - - static double -kurt_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +kurt_get (const struct per_var_data *pvd, void *stat UNUSED) { double kurt; @@ -283,9 +236,8 @@ kurt_get (const const struct means *means UNUSED, struct per_var_data *pvd, void return kurt; } - static double -semean_get (const struct means *means, struct per_var_data *pvd, void *stat) +semean_get (const struct per_var_data *pvd, void *stat UNUSED) { double n, var; @@ -294,12 +246,10 @@ semean_get (const struct means *means, struct per_var_data *pvd, void *stat) return sqrt (var / n); } - - static void * -min_create (const struct means *means UNUSED, struct pool *pool) +min_create (struct pool *pool) { double *r = pool_alloc (pool, sizeof *r); @@ -309,7 +259,7 @@ min_create (const struct means *means UNUSED, struct pool *pool) } static void -min_update (const struct means *means UNUSED, void *stat, double w UNUSED, double x) +min_update (void *stat, double w UNUSED, double x) { double *r = stat; @@ -318,7 +268,7 @@ min_update (const struct means *means UNUSED, void *stat, double w UNUSED, doubl } static double -min_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +min_get (const struct per_var_data *pvd UNUSED, void *stat) { double *r = stat; @@ -326,7 +276,7 @@ min_get (const const struct means *means UNUSED, struct per_var_data *pvd, void } static void * -max_create (const struct means *means UNUSED, struct pool *pool) +max_create (struct pool *pool) { double *r = pool_alloc (pool, sizeof *r); @@ -336,7 +286,7 @@ max_create (const struct means *means UNUSED, struct pool *pool) } static void -max_update (const struct means *means UNUSED, void *stat, double w UNUSED, double x) +max_update (void *stat, double w UNUSED, double x) { double *r = stat; @@ -345,7 +295,7 @@ max_update (const struct means *means UNUSED, void *stat, double w UNUSED, doubl } static double -max_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +max_get (const struct per_var_data *pvd UNUSED, void *stat) { double *r = stat; @@ -361,7 +311,7 @@ struct range }; static void * -range_create (const struct means *means UNUSED, struct pool *pool) +range_create (struct pool *pool) { struct range *r = pool_alloc (pool, sizeof *r); @@ -372,7 +322,7 @@ range_create (const struct means *means UNUSED, struct pool *pool) } static void -range_update (const struct means *means UNUSED, void *stat, double w UNUSED, double x) +range_update (void *stat, double w UNUSED, double x) { struct range *r = stat; @@ -384,7 +334,7 @@ range_update (const struct means *means UNUSED, void *stat, double w UNUSED, dou } static double -range_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +range_get (const struct per_var_data *pvd UNUSED, void *stat) { struct range *r = stat; @@ -394,7 +344,7 @@ range_get (const const struct means *means UNUSED, struct per_var_data *pvd, voi static void * -last_create (const struct means *means UNUSED, struct pool *pool) +last_create (struct pool *pool) { double *l = pool_alloc (pool, sizeof *l); @@ -402,7 +352,7 @@ last_create (const struct means *means UNUSED, struct pool *pool) } static void -last_update (const struct means *means UNUSED, void *stat, double w UNUSED, double x) +last_update (void *stat, double w UNUSED, double x) { double *l = stat; @@ -410,7 +360,7 @@ last_update (const struct means *means UNUSED, void *stat, double w UNUSED, doub } static double -last_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +last_get (const struct per_var_data *pvd UNUSED, void *stat) { double *l = stat; @@ -419,33 +369,38 @@ last_get (const const struct means *means UNUSED, struct per_var_data *pvd, void static void * -first_create (const struct means *means UNUSED, struct pool *pool) +first_create (struct pool *pool) { double *f = pool_alloc (pool, sizeof *f); - *f = SYSMIS; + *f = SYSMIS; return f; } static void -first_update (const struct means *means UNUSED, void *stat, double w UNUSED, double x) +first_update (void *stat, double w UNUSED, double x) { double *f = stat; if (*f == SYSMIS) - *f = x; + *f = x; } static double -first_get (const const struct means *means UNUSED, struct per_var_data *pvd, void *stat) +first_get (const struct per_var_data *pvd UNUSED, void *stat) { double *f = stat; return *f; } - +enum + { + MEANS_MEAN = 0, + MEANS_N, + MEANS_STDDEV + }; /* Table of cell_specs */ static const struct cell_spec cell_spec[] = { @@ -486,23 +441,26 @@ struct summary }; +struct layer +{ + size_t n_factor_vars; + const struct variable **factor_vars; +}; + /* The thing parsed after TABLES= */ struct mtable { size_t n_dep_vars; const struct variable **dep_vars; - size_t n_interactions; + int n_layers; + struct layer *layers; + struct interaction **interactions; struct summary *summary; - size_t *n_factor_vars; - const struct variable ***factor_vars; - int ii; - int n_layers; - struct categoricals *cats; }; @@ -519,6 +477,8 @@ struct means /* Missing value class for dependent variables */ enum mv_class dep_exclude; + bool listwise_exclude; + /* an array indicating which statistics are to be calculated */ int *cells; @@ -534,49 +494,20 @@ static void run_means (struct means *cmd, struct casereader *input, const struct dataset *ds); -/* Append all the variables belonging to layer and all subsequent layers - to iact. And then append iact to the means->interaction. - This is a recursive function. - */ -static void -iact_append_factor (struct mtable *means, int layer, - const struct interaction *iact) -{ - int v; - const struct variable **fv; - - if (layer >= means->n_layers) - return; - fv = means->factor_vars[layer]; - - for (v = 0; v < means->n_factor_vars[layer]; ++v) - { - struct interaction *nexti = interaction_clone (iact); - - interaction_add_variable (nexti, fv[v]); - - iact_append_factor (means, layer + 1, nexti); - - if (layer == means->n_layers - 1) - { - means->interactions[means->ii++] = nexti; - } - } -} static bool parse_means_table_syntax (struct lexer *lexer, const struct means *cmd, struct mtable *table) { table->ii = 0; table->n_layers = 0; - table->factor_vars = NULL; - table->n_factor_vars = NULL; + table->layers = NULL; + table->interactions = NULL; /* Dependent variable (s) */ - if (!parse_variables_const (lexer, cmd->dict, - &table->dep_vars, &table->n_dep_vars, - PV_NO_DUPLICATE | PV_NUMERIC)) + if (!parse_variables_const_pool (lexer, cmd->pool, cmd->dict, + &table->dep_vars, &table->n_dep_vars, + PV_NO_DUPLICATE | PV_NUMERIC)) return false; /* Factor variable (s) */ @@ -585,24 +516,33 @@ parse_means_table_syntax (struct lexer *lexer, const struct means *cmd, struct m if (lex_match (lexer, T_BY)) { table->n_layers++; - table->factor_vars = - xrealloc (table->factor_vars, - sizeof (*table->factor_vars) * table->n_layers); - - table->n_factor_vars = - xrealloc (table->n_factor_vars, - sizeof (*table->n_factor_vars) * table->n_layers); - - if (!parse_variables_const (lexer, cmd->dict, - &table->factor_vars[table->n_layers - 1], - &table->n_factor_vars[table->n_layers - - 1], - PV_NO_DUPLICATE)) + table->layers = + pool_realloc (cmd->pool, table->layers, + sizeof (*table->layers) * table->n_layers); + + if (!parse_variables_const_pool + (lexer, cmd->pool, cmd->dict, + &table->layers[table->n_layers - 1].factor_vars, + &table->layers[table->n_layers - 1].n_factor_vars, + PV_NO_DUPLICATE)) return false; } } + /* There is always at least one layer. + However the final layer is the total, and not + normally considered by the user as a + layer. + */ + + table->n_layers++; + table->layers = + pool_realloc (cmd->pool, table->layers, + sizeof (*table->layers) * table->n_layers); + table->layers[table->n_layers - 1].factor_vars = NULL; + table->layers[table->n_layers - 1].n_factor_vars = 0; + return true; } @@ -635,15 +575,18 @@ cmd_means (struct lexer *lexer, struct dataset *ds) struct means means; bool more_tables = true; + means.pool = pool_create (); + means.exclude = MV_ANY; means.dep_exclude = MV_ANY; + means.listwise_exclude = false; means.table = NULL; means.n_tables = 0; means.dict = dataset_dict (ds); means.n_cells = 3; - means.cells = xcalloc (means.n_cells, sizeof (*means.cells)); + means.cells = pool_calloc (means.pool, means.n_cells, sizeof (*means.cells)); /* The first three items (MEAN, COUNT, STDDEV) are the default */ @@ -663,7 +606,7 @@ cmd_means (struct lexer *lexer, struct dataset *ds) while (more_tables) { means.n_tables ++; - means.table = xrealloc (means.table, means.n_tables * sizeof (*means.table)); + means.table = pool_realloc (means.pool, means.table, means.n_tables * sizeof (*means.table)); if (! parse_means_table_syntax (lexer, &means, &means.table[means.n_tables - 1])) @@ -691,10 +634,10 @@ cmd_means (struct lexer *lexer, struct dataset *ds) if (lex_match_id (lexer, "MISSING")) { /* - If no MISSING subcommand is specified, each combination of - a dependent variable and categorical variables is handled - separately. - */ + If no MISSING subcommand is specified, each combination of + a dependent variable and categorical variables is handled + separately. + */ lex_match (lexer, T_EQUALS); if (lex_match_id (lexer, "INCLUDE")) { @@ -715,22 +658,21 @@ cmd_means (struct lexer *lexer, struct dataset *ds) be dropped FOR THAT TABLE ONLY. */ { - means.exclude = MV_ANY; - means.dep_exclude = MV_ANY; + means.listwise_exclude = true; } else if (lex_match_id (lexer, "DEPENDENT")) /* - Use the command "/MISSING=DEPENDENT" to - include user-missing values for the categorical variables, - while excluding them for the dependent variables. + Use the command "/MISSING=DEPENDENT" to + include user-missing values for the categorical variables, + while excluding them for the dependent variables. - Cases are dropped only when user-missing values - appear in dependent variables. User-missing - values for categorical variables are treated according to - their face value. + Cases are dropped only when user-missing values + appear in dependent variables. User-missing + values for categorical variables are treated according to + their face value. - Cases are ALWAYS dropped when System Missing values appear - in the categorical variables. + Cases are ALWAYS dropped when System Missing values appear + in the categorical variables. */ { means.dep_exclude = MV_ANY; @@ -751,17 +693,44 @@ cmd_means (struct lexer *lexer, struct dataset *ds) while (lex_token (lexer) != T_ENDCMD && lex_token (lexer) != T_SLASH) { - int k; - for (k = 0; k < n_C; ++k) + int k = 0; + if (lex_match (lexer, T_ALL)) { - if (lex_match_id (lexer, cell_spec[k].keyword)) - { - means.cells = - xrealloc (means.cells, - ++means.n_cells * sizeof (*means.cells)); + int x; + means.cells = + pool_realloc (means.pool, means.cells, + (means.n_cells += n_C) * sizeof (*means.cells)); - means.cells[means.n_cells - 1] = k; - break; + for (x = 0; x < n_C; ++x) + means.cells[means.n_cells - (n_C - 1 - x) - 1] = x; + } + else if (lex_match_id (lexer, "NONE")) + { + /* Do nothing */ + } + else if (lex_match_id (lexer, "DEFAULT")) + { + means.cells = + pool_realloc (means.pool, means.cells, + (means.n_cells += 3) * sizeof (*means.cells)); + + means.cells[means.n_cells - 2 - 1] = MEANS_MEAN; + means.cells[means.n_cells - 1 - 1] = MEANS_N; + means.cells[means.n_cells - 0 - 1] = MEANS_STDDEV; + } + else + { + for (; k < n_C; ++k) + { + if (lex_match_id (lexer, cell_spec[k].keyword)) + { + means.cells = + pool_realloc (means.pool, means.cells, + ++means.n_cells * sizeof (*means.cells)); + + means.cells[means.n_cells - 1] = k; + break; + } } } if (k >= n_C) @@ -778,33 +747,31 @@ cmd_means (struct lexer *lexer, struct dataset *ds) } } - means.pool = pool_create (); for (t = 0; t < means.n_tables; ++t) - { - struct mtable *table = &means.table[t]; - table->n_interactions = 1; - for (l = 0; l < table->n_layers; ++l) - { - const int n_vars = table->n_factor_vars[l]; - table->n_interactions *= n_vars; - } - - table->interactions = - xcalloc (table->n_interactions, sizeof (*table->interactions)); - - table->summary = - xcalloc (table->n_dep_vars * table->n_interactions, sizeof (*table->summary)); - + { + struct mtable *table = &means.table[t]; - if (table->n_layers > 0) - iact_append_factor (table, 0, interaction_create (NULL)); - else - table->interactions[0] = interaction_create (NULL); + table->interactions = + pool_calloc (means.pool, table->n_layers, sizeof (*table->interactions)); - } + table->summary = + pool_calloc (means.pool, table->n_dep_vars * table->n_layers, sizeof (*table->summary)); + for (l = 0; l < table->n_layers; ++l) + { + int v; + const struct layer *lyr = &table->layers[l]; + const int n_vars = lyr->n_factor_vars; + table->interactions[l] = interaction_create (NULL); + for (v = 0; v < n_vars ; ++v) + { + interaction_add_variable (table->interactions[l], + lyr->factor_vars[v]); + } + } + } { struct casegrouper *grouper; @@ -820,11 +787,34 @@ cmd_means (struct lexer *lexer, struct dataset *ds) ok = proc_commit (ds) && ok; } + for (t = 0; t < means.n_tables; ++t) + { + int l; + struct mtable *table = &means.table[t]; + if (table->interactions) + for (l = 0; l < table->n_layers; ++l) + { + interaction_destroy (table->interactions[l]); + } + } + pool_destroy (means.pool); return CMD_SUCCESS; -error: + error: + for (t = 0; t < means.n_tables; ++t) + { + int l; + struct mtable *table = &means.table[t]; + if (table->interactions) + for (l = 0; l < table->n_layers; ++l) + { + interaction_destroy (table->interactions[l]); + } + } + + pool_destroy (means.pool); return CMD_FAILURE; } @@ -859,22 +849,38 @@ struct per_cat_data bool warn; }; + +static void +destroy_n (const void *aux1 UNUSED, void *aux2, void *user_data) +{ + struct mtable *table = aux2; + int v; + struct per_cat_data *per_cat_data = user_data; + struct per_var_data *pvd = per_cat_data->pvd; + + for (v = 0; v < table->n_dep_vars; ++v) + { + struct per_var_data *pp = &pvd[v]; + moments1_destroy (pp->mom); + } +} + static void * create_n (const void *aux1, void *aux2) { int i, v; const struct means *means = aux1; struct mtable *table = aux2; - struct per_cat_data *per_cat_data = xmalloc (sizeof *per_cat_data); + struct per_cat_data *per_cat_data = pool_malloc (means->pool, sizeof *per_cat_data); - struct per_var_data *pvd = xcalloc (table->n_dep_vars, sizeof *pvd); + struct per_var_data *pvd = pool_calloc (means->pool, table->n_dep_vars, sizeof *pvd); for (v = 0; v < table->n_dep_vars; ++v) { enum moment maxmom = MOMENT_KURTOSIS; struct per_var_data *pp = &pvd[v]; - pp->cell_stats = xcalloc (means->n_cells, sizeof *pp->cell_stats); + pp->cell_stats = pool_calloc (means->pool, means->n_cells, sizeof *pp->cell_stats); for (i = 0; i < means->n_cells; ++i) @@ -883,7 +889,7 @@ create_n (const void *aux1, void *aux2) const struct cell_spec *cs = &cell_spec[csi]; if (cs->sc) { - pp->cell_stats[i] = cs->sc (means, means->pool); + pp->cell_stats[i] = cs->sc (means->pool); } } pp->mom = moments1_create (maxmom); @@ -896,7 +902,7 @@ create_n (const void *aux1, void *aux2) } static void -update_n (const void *aux1, void *aux2, void *user_data, const struct ccase *c) +update_n (const void *aux1, void *aux2, void *user_data, const struct ccase *c, double weight) { int i; int v = 0; @@ -904,17 +910,16 @@ update_n (const void *aux1, void *aux2, void *user_data, const struct ccase *c) struct mtable *table = aux2; struct per_cat_data *per_cat_data = user_data; - double weight = dict_get_case_weight (means->dict, c, &per_cat_data->warn); - for (v = 0; v < table->n_dep_vars; ++v) { struct per_var_data *pvd = &per_cat_data->pvd[v]; const double x = case_data (c, table->dep_vars[v])->f; - for (i = 0; i < table->n_interactions; ++i) + for (i = 0; i < table->n_layers; ++i) { - if ( is_missing (means, table->dep_vars[v], table->interactions[i], c)) + if ( is_missing (means, table->dep_vars[v], + table->interactions[i], c)) goto end; } @@ -925,8 +930,7 @@ update_n (const void *aux1, void *aux2, void *user_data, const struct ccase *c) if (cs->su) - cs->su (means, - pvd->cell_stats[i], + cs->su (pvd->cell_stats[i], weight, x); } @@ -955,17 +959,16 @@ calculate_n (const void *aux1, void *aux2, void *user_data) const struct cell_spec *cs = &cell_spec[csi]; if (cs->su) - cs->sd (means, pvd, pvd->cell_stats[i]); + cs->sd (pvd, pvd->cell_stats[i]); } } } - static void run_means (struct means *cmd, struct casereader *input, - const struct dataset *ds) + const struct dataset *ds UNUSED) { - int i,t; + int t; const struct variable *wv = dict_get_weight (cmd->dict); struct ccase *c; struct casereader *reader; @@ -973,40 +976,48 @@ run_means (struct means *cmd, struct casereader *input, struct payload payload; payload.create = create_n; payload.update = update_n; - payload.destroy = calculate_n; + payload.calculate = calculate_n; + payload.destroy = destroy_n; for (t = 0; t < cmd->n_tables; ++t) - { - struct mtable *table = &cmd->table[t]; - table->cats - = categoricals_create (table->interactions, - table->n_interactions, wv, cmd->exclude); + { + struct mtable *table = &cmd->table[t]; + table->cats + = categoricals_create (table->interactions, + table->n_layers, wv, cmd->dep_exclude, cmd->exclude); - categoricals_set_payload (table->cats, &payload, cmd, table); - } + categoricals_set_payload (table->cats, &payload, cmd, table); + } - for (reader = casereader_clone (input); + for (reader = input; (c = casereader_read (reader)) != NULL; case_unref (c)) { for (t = 0; t < cmd->n_tables; ++t) { + bool something_missing = false; int v; struct mtable *table = &cmd->table[t]; for (v = 0; v < table->n_dep_vars; ++v) { int i; - for (i = 0; i < table->n_interactions; ++i) + for (i = 0; i < table->n_layers; ++i) { const bool missing = is_missing (cmd, table->dep_vars[v], table->interactions[i], c); if (missing) - table->summary[v * table->n_interactions + i].missing++; + { + something_missing = true; + table->summary[v * table->n_layers + i].missing++; + } else - table->summary[v * table->n_interactions + i].non_missing++; + table->summary[v * table->n_layers + i].non_missing++; } } + if ( something_missing && cmd->listwise_exclude) + continue; + categoricals_update (table->cats, c); } } @@ -1022,20 +1033,22 @@ run_means (struct means *cmd, struct casereader *input, for (t = 0; t < cmd->n_tables; ++t) { + int i; const struct mtable *table = &cmd->table[t]; output_case_processing_summary (table); - for (i = 0; i < table->n_interactions; ++i) + for (i = 0; i < table->n_layers; ++i) { output_report (cmd, i, table); } - categoricals_destroy (table->cats); } + } + static void output_case_processing_summary (const struct mtable *table) { @@ -1044,7 +1057,7 @@ output_case_processing_summary (const struct mtable *table) const int heading_rows = 3; struct tab_table *t; - const int nr = heading_rows + table->n_interactions * table->n_dep_vars; + const int nr = heading_rows + table->n_layers * table->n_dep_vars; const int nc = 7; t = tab_create (nc, nr); @@ -1081,9 +1094,9 @@ output_case_processing_summary (const struct mtable *table) { const struct variable *var = table->dep_vars[v]; const char *dv_name = var_to_string (var); - for (i = 0; i < table->n_interactions; ++i) + for (i = 0; i < table->n_layers; ++i) { - const int row = v * table->n_interactions + i; + const int row = v * table->n_layers + i; const struct interaction *iact = table->interactions[i]; casenumber n_total; @@ -1134,7 +1147,6 @@ output_case_processing_summary (const struct mtable *table) } - static void output_report (const struct means *cmd, int iact_idx, const struct mtable *table) @@ -1162,7 +1174,7 @@ output_report (const struct means *cmd, int iact_idx, tab_box (t, TAL_2, TAL_2, -1, TAL_1, 0, 0, nc - 1, nr - 1); tab_hline (t, TAL_2, 0, nc - 1, heading_rows); - tab_vline (t, TAL_2, iact->n_vars, 0, nr - 1); + tab_vline (t, TAL_2, heading_columns, 0, nr - 1); for (i = 0; i < iact->n_vars; ++i) { @@ -1189,7 +1201,7 @@ output_report (const struct means *cmd, int iact_idx, tab_text (t, 0, heading_rows + dv * n_cats, TAB_RIGHT | TAT_TITLE, - var_get_name (table->dep_vars[dv]) + var_to_string (table->dep_vars[dv]) ); if ( dv > 0) @@ -1225,7 +1237,7 @@ output_report (const struct means *cmd, int iact_idx, const int csi = cmd->cells[i]; const struct cell_spec *cs = &cell_spec[csi]; - double result = cs->sd (cmd, pvd, pvd->cell_stats[i]); + double result = cs->sd (pvd, pvd->cell_stats[i]); tab_double (t, heading_columns + i, heading_rows + grp + dv * n_cats,