From c91d15f0e87c2667ae4b39c236850ef6669a6b51 Mon Sep 17 00:00:00 2001 From: John Darrington Date: Sun, 15 Aug 2010 13:10:37 +0200 Subject: [PATCH] oneway: Fix descriptives for multiple variables --- src/language/stats/glm.q | 2 +- src/language/stats/oneway.c | 96 ++++++++++++++++++++++++------------- src/math/categoricals.c | 22 +++++---- src/math/categoricals.h | 7 +-- 4 files changed, 82 insertions(+), 45 deletions(-) diff --git a/src/language/stats/glm.q b/src/language/stats/glm.q index 0d792df898..4de00e3bb9 100644 --- a/src/language/stats/glm.q +++ b/src/language/stats/glm.q @@ -362,7 +362,7 @@ run_glm (struct casereader *input, struct categoricals *cats = categoricals_create (categoricals, n_categoricals, NULL, MV_NEVER, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); cov = covariance_2pass_create (n_numerics, numerics, cats, diff --git a/src/language/stats/oneway.c b/src/language/stats/oneway.c index f421371c1d..b2d1e5b186 100644 --- a/src/language/stats/oneway.c +++ b/src/language/stats/oneway.c @@ -99,6 +99,7 @@ struct oneway_spec /* The weight variable */ const struct variable *wv; + }; @@ -128,9 +129,8 @@ struct oneway_workspace struct per_var_ws *vws; - struct moments1 *totals; - double minimum; - double maximum; + /* An array of descriptive data. One for each dependent variable */ + struct descriptive_data **dd_total; }; /* Routines to show the output tables */ @@ -268,8 +268,6 @@ cmd_oneway (struct lexer *lexer, struct dataset *ds) struct casereader *group; bool ok; - - grouper = casegrouper_create_splits (proc_open (ds), dict); while (casegrouper_get_next_group (grouper, &group)) run_oneway (&oneway, group, ds); @@ -317,49 +315,76 @@ static void precalc (const struct oneway_spec *cmd); struct descriptive_data { + const struct variable *var; struct moments1 *mom; + double minimum; double maximum; }; -static void * -makeit (void) +static struct descriptive_data * +dd_create (const struct variable *var) { struct descriptive_data *dd = xmalloc (sizeof *dd); + dd->mom = moments1_create (MOMENT_VARIANCE); dd->minimum = DBL_MAX; dd->maximum = -DBL_MAX; + dd->var = var; + + return dd; +} + + +static void * +makeit (void *aux1, void *aux2 UNUSED) +{ + const struct variable *var = aux1; + + struct descriptive_data *dd = dd_create (var); return dd; } static void updateit (void *user_data, const struct variable *wv, - const struct variable *catvar, const struct ccase *c, void *aux) + const struct variable *catvar UNUSED, + const struct ccase *c, + void *aux1, void *aux2) { - const union value *val = case_data_idx (c, 0); struct descriptive_data *dd = user_data; - struct oneway_workspace *ws = aux; + + const struct variable *varp = aux1; + + const union value *valx = case_data (c, varp); + + struct descriptive_data *dd_total = aux2; double weight = 1.0; if (wv) weight = case_data (c, wv)->f; - moments1_add (dd->mom, val->f, weight); - moments1_add (ws->totals, val->f, weight); + moments1_add (dd->mom, valx->f, weight); + if (valx->f * weight < dd->minimum) + dd->minimum = valx->f * weight; - if (val->f * weight < dd->minimum) - dd->minimum = val->f * weight; + if (valx->f * weight > dd->maximum) + dd->maximum = valx->f * weight; - if (val->f * weight > dd->maximum) - dd->maximum = val->f * weight; + { + const struct variable *var = dd_total->var; + const union value *val = case_data (c, var); + moments1_add (dd_total->mom, + val->f, + weight); - if (val->f * weight < ws->minimum) - ws->minimum = val->f * weight; + if (val->f * weight < dd_total->minimum) + dd_total->minimum = val->f * weight; - if (val->f * weight > ws->maximum) - ws->maximum = val->f * weight; + if (val->f * weight > dd_total->maximum) + dd_total->maximum = val->f * weight; + } } static void @@ -374,20 +399,25 @@ run_oneway (const struct oneway_spec *cmd, struct ccase *c; struct oneway_workspace ws; + + { + ws.vws = xmalloc (cmd->n_vars * sizeof (*ws.vws)); - ws.vws = xmalloc (cmd->n_vars * sizeof (*ws.vws)); - - ws.totals = moments1_create (MOMENT_VARIANCE); - ws.minimum = DBL_MAX; - ws.maximum = -DBL_MAX; + ws.dd_total = xmalloc (sizeof (struct descriptive_data) * cmd->n_vars); + for (v = 0 ; v < cmd->n_vars; ++v) + { + ws.dd_total[v] = dd_create (cmd->vars[v]); + } + } for (v = 0; v < cmd->n_vars; ++v) { struct categoricals *cats = categoricals_create (&cmd->indep_var, 1, cmd->wv, cmd->exclude, makeit, - updateit, &ws); + updateit, + cmd->vars[v], ws.dd_total[v]); ws.vws[v].cov = covariance_2pass_create (1, &cmd->vars[v], cats, @@ -886,11 +916,13 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace { double T; double n, mean, variance; + double std_dev; + double std_error; - moments1_calculate (ws->totals, &n, &mean, &variance, NULL, NULL); + moments1_calculate (ws->dd_total[v]->mom, &n, &mean, &variance, NULL, NULL); - double std_dev = sqrt (variance); - double std_error = std_dev / sqrt (n) ; + std_dev = sqrt (variance); + std_error = std_dev / sqrt (n) ; tab_text (t, 1, row + count, TAB_LEFT | TAT_TITLE, _("Total")); @@ -904,7 +936,6 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace tab_double (t, 5, row + count, 0, std_error, NULL); /* Now the confidence interval */ - T = gsl_cdf_tdist_Qinv (q, n - 1); tab_double (t, 6, row + count, 0, @@ -914,9 +945,8 @@ show_descriptives (const struct oneway_spec *cmd, const struct oneway_workspace mean + T * std_error, NULL); /* Min and Max */ - - tab_double (t, 8, row + count, 0, ws->minimum, fmt); - tab_double (t, 9, row + count, 0, ws->maximum, fmt); + tab_double (t, 8, row + count, 0, ws->dd_total[v]->minimum, fmt); + tab_double (t, 9, row + count, 0, ws->dd_total[v]->maximum, fmt); } row += categoricals_total (cats) + 1; diff --git a/src/math/categoricals.c b/src/math/categoricals.c index ef9c528994..1968b332f8 100644 --- a/src/math/categoricals.c +++ b/src/math/categoricals.c @@ -93,11 +93,14 @@ struct categoricals /* Function to be called on each update */ update_func *update; - /* Auxilliary data to be passed to update */ - void *update_aux; /* Function specified by the caller to create user_data */ user_data_create_func *user_data_create; + + + /* Auxilliary data to be passed to update and user_data_create_func*/ + void *aux1; + void *aux2; }; @@ -197,7 +200,7 @@ struct categoricals * categoricals_create (const struct variable *const *v, size_t n_vars, const struct variable *wv, enum mv_class exclude, user_data_create_func *udf, - update_func *update, void *aux + update_func *update, void *aux1, void *aux2 ) { size_t i; @@ -211,9 +214,12 @@ categoricals_create (const struct variable *const *v, size_t n_vars, cat->pool = pool_create (); cat->exclude = exclude; cat->update = update; - cat->update_aux = aux; cat->user_data_create = udf; + cat->aux1 = aux1; + cat->aux2 = aux2; + + cat->vp = pool_calloc (cat->pool, cat->n_vp, sizeof *cat->vp); for (i = 0 ; i < cat->n_vp; ++i) @@ -266,15 +272,15 @@ categoricals_update (struct categoricals *cat, const struct ccase *c) node->subscript = cat->vp[i].n_cats++ ; - if ( cat->user_data_create ) - node->user_data = cat->user_data_create (); + if (cat->user_data_create) + node->user_data = cat->user_data_create (cat->aux1, cat->aux2); } node->cc += weight; cat->vp[i].cc += weight; - if ( cat->update) - cat->update (node->user_data, cat->wv, var, c, cat->update_aux); + if (cat->update) + cat->update (node->user_data, cat->wv, var, c, cat->aux1, cat->aux2); } } diff --git a/src/math/categoricals.h b/src/math/categoricals.h index ff33540ca1..02fef13a30 100644 --- a/src/math/categoricals.h +++ b/src/math/categoricals.h @@ -30,14 +30,15 @@ union value ; typedef void update_func (void *user_data, const struct variable *wv, const struct variable *catvar, - const struct ccase *c, void *aux); + const struct ccase *c, + void *aux1, void *aux2); -typedef void *user_data_create_func (void); +typedef void *user_data_create_func (void *aux1, void *aux2); struct categoricals *categoricals_create (const struct variable *const *v, size_t n_vars, const struct variable *wv, enum mv_class exclude, user_data_create_func *udf, - update_func *update, void *update_aux); + update_func *update, void *aux1, void *aux2); void categoricals_destroy (struct categoricals *); -- 2.30.2