X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fexamine.q;h=50d9525b255d16f1eae307f95d4915a9235425e6;hb=81579d9e9f994fb2908f50af41c3eb033d216e58;hp=361a85bd1e164c194a172da7c1fd8d3a792bec4d;hpb=16af7ed2b7da4aa1c38a15c5663298d6e251e458;p=pspp-builds.git diff --git a/src/language/stats/examine.q b/src/language/stats/examine.q index 361a85bd..50d9525b 100644 --- a/src/language/stats/examine.q +++ b/src/language/stats/examine.q @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2004, 2008 Free Software Foundation, Inc. + Copyright (C) 2004, 2008, 2009, 2010, 2011 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 @@ -17,54 +17,50 @@ #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "minmax.h" -#include "xalloc.h" +#include "data/case.h" +#include "data/casegrouper.h" +#include "data/casereader.h" +#include "data/casewriter.h" +#include "data/dictionary.h" +#include "data/procedure.h" +#include "data/subcase.h" +#include "data/value-labels.h" +#include "data/variable.h" +#include "language/command.h" +#include "language/dictionary/split-file.h" +#include "language/lexer/lexer.h" +#include "libpspp/compiler.h" +#include "libpspp/message.h" +#include "libpspp/misc.h" +#include "libpspp/str.h" +#include "math/box-whisker.h" +#include "math/extrema.h" +#include "math/histogram.h" +#include "math/moments.h" +#include "math/np.h" +#include "math/order-stats.h" +#include "math/percentiles.h" +#include "math/sort.h" +#include "math/trimmed-mean.h" +#include "math/tukey-hinges.h" +#include "output/chart-item.h" +#include "output/charts/boxplot.h" +#include "output/charts/np-plot.h" +#include "output/charts/plot-hist.h" +#include "output/tab.h" + +#include "gl/minmax.h" +#include "gl/xalloc.h" #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) msgid /* (headers) */ -#include -#include -#include -#include /* (specification) "EXAMINE" (xmn_): @@ -104,11 +100,11 @@ struct factor_metrics struct percentile **ptl; size_t n_ptiles; - struct statistic *tukey_hinges; - struct statistic *box_whisker; - struct statistic *trimmed_mean; - struct statistic *histogram; - struct order_stats *np; + struct tukey_hinges *tukey_hinges; + struct box_whisker *box_whisker; + struct trimmed_mean *trimmed_mean; + struct histogram *histogram; + struct np *np; /* Three quartiles indexing into PTL */ struct percentile **quartiles; @@ -122,6 +118,9 @@ struct factor_metrics /* Sum of all weights, including those for missing values */ double n; + /* Sum of weights of non_missing values */ + double n_valid; + double mean; double variance; @@ -140,7 +139,7 @@ struct factor_result { struct ll ll; - union value *value[2]; + union value value[2]; /* An array of factor metrics, one for each variable */ struct factor_metrics *metrics; @@ -168,6 +167,7 @@ factor_destroy (struct xfactor *fctr) int v; struct factor_result *result = ll_data (ll, struct factor_result, ll); + int i; for (v = 0; v < n_dependent_vars; ++v) { @@ -175,19 +175,21 @@ factor_destroy (struct xfactor *fctr) moments1_destroy (result->metrics[v].moments); extrema_destroy (result->metrics[v].minima); extrema_destroy (result->metrics[v].maxima); - statistic_destroy (result->metrics[v].trimmed_mean); - statistic_destroy (result->metrics[v].tukey_hinges); - statistic_destroy (result->metrics[v].box_whisker); - statistic_destroy (result->metrics[v].histogram); + statistic_destroy (&result->metrics[v].trimmed_mean->parent.parent); + statistic_destroy (&result->metrics[v].tukey_hinges->parent.parent); + statistic_destroy (&result->metrics[v].box_whisker->parent.parent); + statistic_destroy (&result->metrics[v].histogram->parent); for (i = 0 ; i < result->metrics[v].n_ptiles; ++i) - statistic_destroy ((struct statistic *) result->metrics[v].ptl[i]); + statistic_destroy (&result->metrics[v].ptl[i]->parent.parent); free (result->metrics[v].ptl); free (result->metrics[v].quartiles); casereader_destroy (result->metrics[v].up_reader); } - free (result->value[0]); - free (result->value[1]); + for (i = 0; i < 2; i++) + if (fctr->indep_var[i]) + value_destroy (&result->value[i], + var_get_width (fctr->indep_var[i])); free (result->metrics); ll = ll_next (ll); free (result); @@ -195,7 +197,7 @@ factor_destroy (struct xfactor *fctr) } static struct xfactor level0_factor; -static struct ll_list factor_list = LL_INITIALIZER (factor_list); +static struct ll_list factor_list; /* Parse the clause specifying the factors */ static int examine_parse_independent_vars (struct lexer *lexer, @@ -204,6 +206,7 @@ static int examine_parse_independent_vars (struct lexer *lexer, /* Output functions */ static void show_summary (const struct variable **dependent_var, int n_dep_var, + const struct dictionary *dict, const struct xfactor *f); @@ -228,7 +231,7 @@ static void show_extremes (const struct variable **dependent_var, static void run_examine (struct cmd_examine *, struct casereader *, struct dataset *); -static void output_examine (void); +static void output_examine (const struct dictionary *dict); void factor_calc (const struct ccase *c, int case_no, @@ -265,6 +268,8 @@ cmd_examine (struct lexer *lexer, struct dataset *ds) subc_list_double_create (&percentile_list); percentile_algorithm = PC_HAVERAGE; + ll_init (&factor_list); + if ( !parse_examine (lexer, ds, &cmd, NULL) ) { subc_list_double_destroy (&percentile_list); @@ -311,82 +316,6 @@ cmd_examine (struct lexer *lexer, struct dataset *ds) }; -/* Plot the normal and detrended normal plots for RESULT. - Label the plots with LABEL */ -static void -np_plot (struct np *np, const char *label) -{ - double yfirst = 0, ylast = 0; - - double x_lower; - double x_upper; - double slack; - - /* Normal Plot */ - struct chart *np_chart; - - /* Detrended Normal Plot */ - struct chart *dnp_chart; - - /* The slope and intercept of the ideal normal probability line */ - const double slope = 1.0 / np->stddev; - const double intercept = -np->mean / np->stddev; - - if ( np->n < 1.0 ) - { - msg (MW, _("Not creating plot because data set is empty.")); - return ; - } - - np_chart = chart_create (); - dnp_chart = chart_create (); - - if ( !np_chart || ! dnp_chart ) - return ; - - chart_write_title (np_chart, _("Normal Q-Q Plot of %s"), label); - chart_write_xlabel (np_chart, _("Observed Value")); - chart_write_ylabel (np_chart, _("Expected Normal")); - - chart_write_title (dnp_chart, _("Detrended Normal Q-Q Plot of %s"), - label); - chart_write_xlabel (dnp_chart, _("Observed Value")); - chart_write_ylabel (dnp_chart, _("Dev from Normal")); - - yfirst = gsl_cdf_ugaussian_Pinv (1 / (np->n + 1)); - ylast = gsl_cdf_ugaussian_Pinv (np->n / (np->n + 1)); - - /* Need to make sure that both the scatter plot and the ideal fit into the - plot */ - x_lower = MIN (np->y_min, (yfirst - intercept) / slope) ; - x_upper = MAX (np->y_max, (ylast - intercept) / slope) ; - slack = (x_upper - x_lower) * 0.05 ; - - chart_write_xscale (np_chart, x_lower - slack, x_upper + slack, 5); - chart_write_xscale (dnp_chart, np->y_min, np->y_max, 5); - - chart_write_yscale (np_chart, yfirst, ylast, 5); - chart_write_yscale (dnp_chart, np->dns_min, np->dns_max, 5); - - { - struct ccase c; - struct casereader *reader = casewriter_make_reader (np->writer); - while (casereader_read (reader, &c)) - { - chart_datum (np_chart, 0, case_data_idx (&c, NP_IDX_Y)->f, case_data_idx (&c, NP_IDX_NS)->f); - chart_datum (dnp_chart, 0, case_data_idx (&c, NP_IDX_Y)->f, case_data_idx (&c, NP_IDX_DNS)->f); - - case_destroy (&c); - } - casereader_destroy (reader); - } - - chart_line (dnp_chart, 0, 0, np->y_min, np->y_max , CHART_DIM_X); - chart_line (np_chart, slope, intercept, yfirst, ylast , CHART_DIM_Y); - - chart_submit (np_chart); - chart_submit (dnp_chart); -} static void @@ -403,20 +332,38 @@ show_npplot (const struct variable **dependent_var, ll != ll_null (&fctr->result_list); ll = ll_next (ll)) { - struct string str; + struct string label; const struct factor_result *result = ll_data (ll, struct factor_result, ll); - - ds_init_empty (&str); - ds_put_format (&str, "%s ", var_get_name (dependent_var[v])); - - factor_to_string (fctr, result, &str); - - np_plot ((struct np*) result->metrics[v].np, ds_cstr(&str)); - - statistic_destroy ((struct statistic *)result->metrics[v].np); - - ds_destroy (&str); + struct chart_item *npp, *dnpp; + struct casereader *reader; + struct np *np; + + ds_init_empty (&label); + ds_put_format (&label, "%s ", var_get_name (dependent_var[v])); + factor_to_string (fctr, result, &label); + + np = result->metrics[v].np; + reader = casewriter_make_reader (np->writer); + npp = np_plot_create (np, reader, ds_cstr (&label)); + dnpp = dnp_plot_create (np, reader, ds_cstr (&label)); + + ds_destroy (&label); + + if (npp == NULL || dnpp == NULL) + { + msg (MW, _("Not creating NP plot because data set is empty.")); + chart_item_unref (npp); + chart_item_unref (dnpp); + } + else + { + chart_item_submit (npp); + chart_item_submit (dnpp); + } + + statistic_destroy (&np->parent.parent); + casereader_destroy (reader); } } } @@ -439,15 +386,26 @@ show_histogram (const struct variable **dependent_var, struct string str; const struct factor_result *result = ll_data (ll, struct factor_result, ll); + struct histogram *histogram; + double mean, var, n; + + histogram = result->metrics[v].histogram; + if (histogram == NULL) + { + /* Probably all values are SYSMIS. */ + continue; + } ds_init_empty (&str); ds_put_format (&str, "%s ", var_get_name (dependent_var[v])); factor_to_string (fctr, result, &str); - histogram_plot ((struct histogram *) result->metrics[v].histogram, - ds_cstr (&str), - (struct moments1 *) result->metrics[v].moments); + moments1_calculate (result->metrics[v].moments, + &n, &mean, &var, NULL, NULL); + chart_item_submit (histogram_chart_create (histogram->gsl_hist, + ds_cstr (&str), n, mean, + sqrt (var), false)); ds_destroy (&str); } @@ -465,25 +423,18 @@ show_boxplot_groups (const struct variable **dependent_var, for (v = 0; v < n_dep_var; ++v) { - struct ll *ll; - int f = 0; - struct chart *ch = chart_create (); + const struct factor_result *result; + struct boxplot *boxplot; double y_min = DBL_MAX; double y_max = -DBL_MAX; + char *title; - for (ll = ll_head (&fctr->result_list); - ll != ll_null (&fctr->result_list); - ll = ll_next (ll)) + ll_for_each (result, struct factor_result, ll, &fctr->result_list) { + struct factor_metrics *metrics = &result->metrics[v]; + const struct ll_list *max_list = extrema_list (metrics->maxima); + const struct ll_list *min_list = extrema_list (metrics->minima); const struct extremum *max, *min; - const struct factor_result *result = - ll_data (ll, struct factor_result, ll); - - const struct ll_list *max_list = - extrema_list (result->metrics[v].maxima); - - const struct ll_list *min_list = - extrema_list (result->metrics[v].minima); if ( ll_is_empty (max_list)) { @@ -491,52 +442,34 @@ show_boxplot_groups (const struct variable **dependent_var, continue; } - max = (const struct extremum *) - ll_data (ll_head(max_list), struct extremum, ll); - - min = (const struct extremum *) - ll_data (ll_head (min_list), struct extremum, ll); + max = ll_data (ll_head(max_list), struct extremum, ll); + min = ll_data (ll_head (min_list), struct extremum, ll); y_max = MAX (y_max, max->value); y_min = MIN (y_min, min->value); } - boxplot_draw_yscale (ch, y_max, y_min); - - if ( fctr->indep_var[0]) - chart_write_title (ch, _("Boxplot of %s vs. %s"), + if (fctr->indep_var[0]) + title = xasprintf (_("Boxplot of %s vs. %s"), var_to_string (dependent_var[v]), - var_to_string (fctr->indep_var[0]) ); + var_to_string (fctr->indep_var[0])); else - chart_write_title (ch, _("Boxplot of %s"), - var_to_string (dependent_var[v])); + title = xasprintf (_("Boxplot of %s"), + var_to_string (dependent_var[v])); + boxplot = boxplot_create (y_min, y_max, title); + free (title); - for (ll = ll_head (&fctr->result_list); - ll != ll_null (&fctr->result_list); - ll = ll_next (ll)) + ll_for_each (result, struct factor_result, ll, &fctr->result_list) { - const struct factor_result *result = - ll_data (ll, struct factor_result, ll); - - struct string str; - const double box_width = (ch->data_right - ch->data_left) - / (ll_count (&fctr->result_list) * 2.0 ) ; - - const double box_centre = (f++ * 2 + 1) * box_width + ch->data_left; - - ds_init_empty (&str); + struct factor_metrics *metrics = &result->metrics[v]; + struct string str = DS_EMPTY_INITIALIZER; factor_to_string_concise (fctr, result, &str); - - boxplot_draw_boxplot (ch, - box_centre, box_width, - (const struct box_whisker *) - result->metrics[v].box_whisker, - ds_cstr (&str)); - + boxplot_add_box (boxplot, metrics->box_whisker, ds_cstr (&str)); + metrics->box_whisker = NULL; ds_destroy (&str); } - chart_submit (ch); + boxplot_submit (boxplot); } } @@ -549,85 +482,53 @@ show_boxplot_variables (const struct variable **dependent_var, ) { + const struct factor_result *result; int v; - struct ll *ll; - const struct ll_list *result_list = &fctr->result_list; - - for (ll = ll_head (result_list); - ll != ll_null (result_list); - ll = ll_next (ll)) + ll_for_each (result, struct factor_result, ll, &fctr->result_list) { struct string title; - struct chart *ch = chart_create (); double y_min = DBL_MAX; double y_max = -DBL_MAX; - - const struct factor_result *result = - ll_data (ll, struct factor_result, ll); - - const double box_width = (ch->data_right - ch->data_left) - / (n_dep_var * 2.0 ) ; + struct boxplot *boxplot; for (v = 0; v < n_dep_var; ++v) { - const struct ll *max_ll = - ll_head (extrema_list (result->metrics[v].maxima)); - const struct ll *min_ll = - ll_head (extrema_list (result->metrics[v].minima)); - - const struct extremum *max = - (const struct extremum *) ll_data (max_ll, struct extremum, ll); - - const struct extremum *min = - (const struct extremum *) ll_data (min_ll, struct extremum, ll); + const struct factor_metrics *metrics = &result->metrics[v]; + const struct ll *max_ll = ll_head (extrema_list (metrics->maxima)); + const struct ll *min_ll = ll_head (extrema_list (metrics->minima)); + const struct extremum *max = ll_data (max_ll, struct extremum, ll); + const struct extremum *min = ll_data (min_ll, struct extremum, ll); y_max = MAX (y_max, max->value); y_min = MIN (y_min, min->value); } - - boxplot_draw_yscale (ch, y_max, y_min); - ds_init_empty (&title); factor_to_string (fctr, result, &title); - -#if 0 - ds_put_format (&title, "%s = ", var_get_name (fctr->indep_var[0])); - var_append_value_name (fctr->indep_var[0], result->value[0], &title); -#endif - - chart_write_title (ch, ds_cstr (&title)); + boxplot = boxplot_create (y_min, y_max, ds_cstr (&title)); ds_destroy (&title); for (v = 0; v < n_dep_var; ++v) { - struct string str; - const double box_centre = (v * 2 + 1) * box_width + ch->data_left; - - ds_init_empty (&str); - ds_init_cstr (&str, var_get_name (dependent_var[v])); - - boxplot_draw_boxplot (ch, - box_centre, box_width, - (const struct box_whisker *) result->metrics[v].box_whisker, - ds_cstr (&str)); - - ds_destroy (&str); + struct factor_metrics *metrics = &result->metrics[v]; + boxplot_add_box (boxplot, metrics->box_whisker, + var_get_name (dependent_var[v])); + metrics->box_whisker = NULL; } - chart_submit (ch); + boxplot_submit (boxplot); } } /* Show all the appropriate tables */ static void -output_examine (void) +output_examine (const struct dictionary *dict) { struct ll *ll; - show_summary (dependent_vars, n_dependent_vars, &level0_factor); + show_summary (dependent_vars, n_dependent_vars, dict, &level0_factor); if ( cmd.a_statistics[XMN_ST_EXTREME] ) show_extremes (dependent_vars, n_dependent_vars, &level0_factor); @@ -654,7 +555,7 @@ output_examine (void) ll != ll_null (&factor_list); ll = ll_next (ll)) { struct xfactor *factor = ll_data (ll, struct xfactor, ll); - show_summary (dependent_vars, n_dependent_vars, factor); + show_summary (dependent_vars, n_dependent_vars, dict, factor); if ( cmd.a_statistics[XMN_ST_EXTREME] ) show_extremes (dependent_vars, n_dependent_vars, factor); @@ -665,16 +566,14 @@ output_examine (void) if ( cmd.sbc_percentiles) show_percentiles (dependent_vars, n_dependent_vars, factor); - if (cmd.a_plot[XMN_PLT_BOXPLOT] && - cmd.cmp == XMN_GROUPS) - show_boxplot_groups (dependent_vars, n_dependent_vars, factor); - - - if (cmd.a_plot[XMN_PLT_BOXPLOT] && - cmd.cmp == XMN_VARIABLES) - show_boxplot_variables (dependent_vars, n_dependent_vars, - factor); - + if (cmd.a_plot[XMN_PLT_BOXPLOT]) + { + if (cmd.cmp == XMN_GROUPS) + show_boxplot_groups (dependent_vars, n_dependent_vars, factor); + else if (cmd.cmp == XMN_VARIABLES) + show_boxplot_variables (dependent_vars, n_dependent_vars, factor); + } + if (cmd.a_plot[XMN_PLT_HISTOGRAM]) show_histogram (dependent_vars, n_dependent_vars, factor); @@ -688,9 +587,9 @@ static int xmn_custom_percentiles (struct lexer *lexer, struct dataset *ds UNUSED, struct cmd_examine *p UNUSED, void *aux UNUSED) { - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); - lex_match (lexer, '('); + lex_match (lexer, T_LPAREN); while ( lex_is_number (lexer) ) { @@ -698,11 +597,11 @@ xmn_custom_percentiles (struct lexer *lexer, struct dataset *ds UNUSED, lex_get (lexer); - lex_match (lexer, ',') ; + lex_match (lexer, T_COMMA) ; } - lex_match (lexer, ')'); + lex_match (lexer, T_RPAREN); - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); if ( lex_match_id (lexer, "HAVERAGE")) percentile_algorithm = PC_HAVERAGE; @@ -774,9 +673,9 @@ xmn_custom_variables (struct lexer *lexer, struct dataset *ds, void *aux UNUSED) { const struct dictionary *dict = dataset_dict (ds); - lex_match (lexer, '='); + lex_match (lexer, T_EQUALS); - if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokid (lexer)) == NULL) + if ( (lex_token (lexer) != T_ID || dict_lookup_var (dict, lex_tokcstr (lexer)) == NULL) && lex_token (lexer) != T_ALL) { return 2; @@ -820,7 +719,7 @@ examine_parse_independent_vars (struct lexer *lexer, ll_init (&sf->result_list); if ( (lex_token (lexer) != T_ID || - dict_lookup_var (dict, lex_tokid (lexer)) == NULL) + dict_lookup_var (dict, lex_tokcstr (lexer)) == NULL) && lex_token (lexer) != T_ALL) { free ( sf ) ; @@ -835,7 +734,7 @@ examine_parse_independent_vars (struct lexer *lexer, lex_match (lexer, T_BY); if ( (lex_token (lexer) != T_ID || - dict_lookup_var (dict, lex_tokid (lexer)) == NULL) + dict_lookup_var (dict, lex_tokcstr (lexer)) == NULL) && lex_token (lexer) != T_ALL) { free (sf); @@ -849,9 +748,9 @@ examine_parse_independent_vars (struct lexer *lexer, else ll_push_tail (&factor_list, &sf->ll); - lex_match (lexer, ','); + lex_match (lexer, T_COMMA); - if ( lex_token (lexer) == '.' || lex_token (lexer) == '/' ) + if ( lex_token (lexer) == T_ENDCMD || lex_token (lexer) == T_SLASH ) return 1; success = examine_parse_independent_vars (lexer, dict, cmd); @@ -866,11 +765,16 @@ static void examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, const struct dictionary *dict, struct xfactor *factor) { - struct ccase c; + struct ccase *c; const struct variable *wv = dict_get_weight (dict); int v; int n_extrema = 1; struct factor_result *result = xzalloc (sizeof (*result)); + int i; + + for (i = 0; i < 2; i++) + if (factor->indep_var[i]) + value_init (&result->value[i], var_get_width (factor->indep_var[i])); result->metrics = xcalloc (n_dependent_vars, sizeof (*result->metrics)); @@ -878,20 +782,15 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, n_extrema = cmd->st_n; - if (casereader_peek (reader, 0, &c)) + c = casereader_peek (reader, 0); + if (c != NULL) { if ( level > 0) - { - result->value[0] = - value_dup (case_data (&c, factor->indep_var[0]), - var_get_width (factor->indep_var[0])); - - if ( level > 1) - result->value[1] = - value_dup (case_data (&c, factor->indep_var[1]), - var_get_width (factor->indep_var[1])); - } - case_destroy (&c); + for (i = 0; i < 2; i++) + if (factor->indep_var[i]) + value_copy (&result->value[i], case_data (c, factor->indep_var[i]), + var_get_width (factor->indep_var[i])); + case_unref (c); } for (v = 0; v < n_dependent_vars; ++v) @@ -911,49 +810,53 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, { /* In this case, we need to sort the data, so we create a sorting casewriter */ - struct case_ordering *up_ordering = case_ordering_create (); - - case_ordering_add_var (up_ordering, dependent_vars[v], SRT_ASCEND); - writer = sort_create_writer (up_ordering, - casereader_get_value_cnt (reader)); + struct subcase up_ordering; + subcase_init_var (&up_ordering, dependent_vars[v], SC_ASCEND); + writer = sort_create_writer (&up_ordering, + casereader_get_proto (reader)); + subcase_destroy (&up_ordering); } else { /* but in this case, sorting is unnecessary, so an ordinary casewriter is sufficient */ writer = - autopaging_writer_create (casereader_get_value_cnt (reader)); + autopaging_writer_create (casereader_get_proto (reader)); } /* Sort or just iterate, whilst calculating moments etc */ - while (casereader_read (input, &c)) + while ((c = casereader_read (input)) != NULL) { - const casenumber loc = - case_data_idx (&c, casereader_get_value_cnt (reader) - 1)->f; + int n_vals = caseproto_get_n_widths (casereader_get_proto (reader)); + const casenumber loc = case_data_idx (c, n_vals - 1)->f; - const double weight = wv ? case_data (&c, wv)->f : 1.0; + const double weight = wv ? case_data (c, wv)->f : 1.0; + const union value *value = case_data (c, dependent_vars[v]); if (weight != SYSMIS) minimize (&result->metrics[v].cmin, weight); moments1_add (result->metrics[v].moments, - case_data (&c, dependent_vars[v])->f, + value->f, weight); result->metrics[v].n += weight; + if ( ! var_is_value_missing (dependent_vars[v], value, MV_ANY) ) + result->metrics[v].n_valid += weight; + extrema_add (result->metrics[v].maxima, - case_data (&c, dependent_vars[v])->f, + value->f, weight, loc); extrema_add (result->metrics[v].minima, - case_data (&c, dependent_vars[v])->f, + value->f, weight, loc); - casewriter_write (writer, &c); + casewriter_write (writer, c); } casereader_destroy (input); result->metrics[v].up_reader = casewriter_make_reader (writer); @@ -976,15 +879,13 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, metric->n_ptiles = percentile_list.n_data; - metric->ptl = xcalloc (metric->n_ptiles, - sizeof (struct percentile *)); + metric->ptl = xcalloc (metric->n_ptiles, sizeof *metric->ptl); metric->quartiles = xcalloc (3, sizeof (*metric->quartiles)); for (i = 0 ; i < metric->n_ptiles; ++i) { - metric->ptl[i] = (struct percentile *) - percentile_create (percentile_list.data[i] / 100.0, metric->n); + metric->ptl[i] = percentile_create (percentile_list.data[i] / 100.0, metric->n_valid); if ( percentile_list.data[i] == 25) metric->quartiles[0] = metric->ptl[i]; @@ -994,8 +895,8 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, metric->quartiles[2] = metric->ptl[i]; } - metric->tukey_hinges = tukey_hinges_create (metric->n, metric->cmin); - metric->trimmed_mean = trimmed_mean_create (metric->n, 0.05); + metric->tukey_hinges = tukey_hinges_create (metric->n_valid, metric->cmin); + metric->trimmed_mean = trimmed_mean_create (metric->n_valid, 0.05); n_os = metric->n_ptiles + 2; @@ -1005,18 +906,18 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, n_os ++; } - os = xcalloc (sizeof (struct order_stats *), n_os); + os = xcalloc (n_os, sizeof *os); for (i = 0 ; i < metric->n_ptiles ; ++i ) { - os[i] = (struct order_stats *) metric->ptl[i]; + os[i] = &metric->ptl[i]->parent; } - os[i] = (struct order_stats *) metric->tukey_hinges; - os[i+1] = (struct order_stats *) metric->trimmed_mean; + os[i] = &metric->tukey_hinges->parent; + os[i+1] = &metric->trimmed_mean->parent; if (cmd->a_plot[XMN_PLT_NPPLOT]) - os[i+2] = metric->np; + os[i+2] = &metric->np->parent; order_stats_accumulate (os, n_os, casereader_clone (metric->up_reader), @@ -1028,7 +929,7 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, /* FIXME: Do this in the above loop */ if ( cmd->a_plot[XMN_PLT_HISTOGRAM] ) { - struct ccase c; + struct ccase *c; struct casereader *input = casereader_clone (reader); for (v = 0; v < n_dependent_vars; ++v) @@ -1059,18 +960,18 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, metric->histogram = histogram_create (10, min->value, max->value); } - while (casereader_read (input, &c)) + while ((c = casereader_read (input)) != NULL) { - const double weight = wv ? case_data (&c, wv)->f : 1.0; + const double weight = wv ? case_data (c, wv)->f : 1.0; for (v = 0; v < n_dependent_vars; ++v) { struct factor_metrics *metric = &result->metrics[v]; if ( metric->histogram) - histogram_add ((struct histogram *) metric->histogram, - case_data (&c, dependent_vars[v])->f, weight); + histogram_add (metric->histogram, + case_data (c, dependent_vars[v])->f, weight); } - case_destroy (&c); + case_unref (c); } casereader_destroy (input); } @@ -1081,15 +982,15 @@ examine_group (struct cmd_examine *cmd, struct casereader *reader, int level, for (v = 0; v < n_dependent_vars; ++v) { struct factor_metrics *metric = &result->metrics[v]; + int n_vals = caseproto_get_n_widths (casereader_get_proto ( + metric->up_reader)); + struct order_stats *os; metric->box_whisker = - box_whisker_create ((struct tukey_hinges *) metric->tukey_hinges, - cmd->v_id, - casereader_get_value_cnt (metric->up_reader) - - 1); + box_whisker_create ( metric->tukey_hinges, cmd->v_id, n_vals - 1); - order_stats_accumulate ((struct order_stats **) &metric->box_whisker, - 1, + os = &metric->box_whisker->parent; + order_stats_accumulate ( &os, 1, casereader_clone (metric->up_reader), wv, dependent_vars[v], MV_ANY); } @@ -1106,17 +1007,18 @@ run_examine (struct cmd_examine *cmd, struct casereader *input, { struct ll *ll; const struct dictionary *dict = dataset_dict (ds); - struct ccase c; + struct ccase *c; struct casereader *level0 = casereader_clone (input); - if (!casereader_peek (input, 0, &c)) + c = casereader_peek (input, 0); + if (c == NULL) { casereader_destroy (input); return; } - output_split_file_values (ds, &c); - case_destroy (&c); + output_split_file_values (ds, c); + case_unref (c); ll_init (&level0_factor.result_list); @@ -1131,15 +1033,10 @@ run_examine (struct cmd_examine *cmd, struct casereader *input, struct casereader *group = NULL; struct casereader *level1; struct casegrouper *grouper1 = NULL; - struct case_ordering *ordering1 = case_ordering_create (); - case_ordering_add_var (ordering1, factor->indep_var[0], SRT_ASCEND); level1 = casereader_clone (input); - - level1 = sort_execute (level1, - case_ordering_clone (ordering1)); - grouper1 = casegrouper_create_case_ordering (level1, ordering1); - case_ordering_destroy (ordering1); + level1 = sort_execute_1var (level1, factor->indep_var[0]); + grouper1 = casegrouper_create_vars (level1, &factor->indep_var[0], 1); while (casegrouper_get_next_group (grouper1, &group)) { @@ -1152,16 +1049,12 @@ run_examine (struct cmd_examine *cmd, struct casereader *input, int n_groups = 0; struct casereader *group2 = NULL; struct casegrouper *grouper2 = NULL; - struct case_ordering *ordering2 = case_ordering_create (); - case_ordering_add_var (ordering2, - factor->indep_var[1], SRT_ASCEND); - group_copy = sort_execute (group_copy, - case_ordering_clone (ordering2)); - grouper2 = - casegrouper_create_case_ordering (group_copy, ordering2); + group_copy = sort_execute_1var (group_copy, + factor->indep_var[1]); - case_ordering_destroy (ordering2); + grouper2 = casegrouper_create_vars (group_copy, + &factor->indep_var[1], 1); while (casegrouper_get_next_group (grouper2, &group2)) { @@ -1178,7 +1071,7 @@ run_examine (struct cmd_examine *cmd, struct casereader *input, casereader_destroy (input); - output_examine (); + output_examine (dict); factor_destroy (&level0_factor); @@ -1198,8 +1091,12 @@ run_examine (struct cmd_examine *cmd, struct casereader *input, static void show_summary (const struct variable **dependent_var, int n_dep_var, + const struct dictionary *dict, const struct xfactor *fctr) { + const struct variable *wv = dict_get_weight (dict); + const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : & F_8_0; + static const char *subtitle[]= { N_("Valid"), @@ -1233,11 +1130,9 @@ show_summary (const struct variable **dependent_var, int n_dep_var, n_cols = heading_columns + 6; - tbl = tab_create (n_cols, n_rows, 0); + tbl = tab_create (n_cols, n_rows); tab_headers (tbl, heading_columns, 0, heading_rows, 0); - tab_dim (tbl, tab_natural_dimensions); - /* Outline the box */ tab_box (tbl, TAL_2, TAL_2, @@ -1311,7 +1206,7 @@ show_summary (const struct variable **dependent_var, int n_dep_var, { int j = 0; struct ll *ll; - union value *last_value = NULL; + const union value *last_value = NULL; if ( v > 0 ) tab_hline (tbl, TAL_1, 0, n_cols -1 , @@ -1337,15 +1232,15 @@ show_summary (const struct variable **dependent_var, int n_dep_var, { if ( last_value == NULL || - compare_values_short (last_value, result->value[0], - fctr->indep_var[0])) + !value_equal (last_value, &result->value[0], + var_get_width (fctr->indep_var[0]))) { struct string str; - last_value = result->value[0]; + last_value = &result->value[0]; ds_init_empty (&str); - var_append_value_name (fctr->indep_var[0], result->value[0], + var_append_value_name (fctr->indep_var[0], &result->value[0], &str); tab_text (tbl, 1, @@ -1369,7 +1264,7 @@ show_summary (const struct variable **dependent_var, int n_dep_var, ds_init_empty (&str); var_append_value_name (fctr->indep_var[1], - result->value[1], &str); + &result->value[1], &str); tab_text (tbl, 2, heading_rows + j + @@ -1391,43 +1286,43 @@ show_summary (const struct variable **dependent_var, int n_dep_var, result->metrics[v].se_mean = sqrt (result->metrics[v].variance / n) ; /* Total Valid */ - tab_float (tbl, heading_columns, + tab_double (tbl, heading_columns, heading_rows + j + v * ll_count (&fctr->result_list), TAB_LEFT, - n, 8, 0); + n, wfmt); - tab_text (tbl, heading_columns + 1, - heading_rows + j + v * ll_count (&fctr->result_list), - TAB_RIGHT | TAT_PRINTF, - "%g%%", n * 100.0 / result->metrics[v].n); + tab_text_format (tbl, heading_columns + 1, + heading_rows + j + v * ll_count (&fctr->result_list), + TAB_RIGHT, + "%g%%", n * 100.0 / result->metrics[v].n); /* Total Missing */ - tab_float (tbl, heading_columns + 2, + tab_double (tbl, heading_columns + 2, heading_rows + j + v * ll_count (&fctr->result_list), TAB_LEFT, result->metrics[v].n - n, - 8, 0); + wfmt); - tab_text (tbl, heading_columns + 3, - heading_rows + j + v * ll_count (&fctr->result_list), - TAB_RIGHT | TAT_PRINTF, - "%g%%", - (result->metrics[v].n - n) * 100.0 / result->metrics[v].n - ); + tab_text_format (tbl, heading_columns + 3, + heading_rows + j + v * ll_count (&fctr->result_list), + TAB_RIGHT, + "%g%%", + (result->metrics[v].n - n) * 100.0 / result->metrics[v].n + ); /* Total Valid + Missing */ - tab_float (tbl, heading_columns + 4, + tab_double (tbl, heading_columns + 4, heading_rows + j + v * ll_count (&fctr->result_list), TAB_LEFT, result->metrics[v].n, - 8, 0); + wfmt); - tab_text (tbl, heading_columns + 5, - heading_rows + j + v * ll_count (&fctr->result_list), - TAB_RIGHT | TAT_PRINTF, - "%g%%", - (result->metrics[v].n) * 100.0 / result->metrics[v].n - ); + tab_text_format (tbl, heading_columns + 5, + heading_rows + j + v * ll_count (&fctr->result_list), + TAB_RIGHT, + "%g%%", + ((result->metrics[v].n) * 100.0 + / result->metrics[v].n)); ++j; } @@ -1470,11 +1365,9 @@ show_descriptives (const struct variable **dependent_var, n_cols = heading_columns + 2; - tbl = tab_create (n_cols, n_rows, 0); + tbl = tab_create (n_cols, n_rows); tab_headers (tbl, heading_columns, 0, heading_rows, 0); - tab_dim (tbl, tab_natural_dimensions); - /* Outline the box */ tab_box (tbl, TAL_2, TAL_2, @@ -1532,7 +1425,7 @@ show_descriptives (const struct variable **dependent_var, struct string vstr; ds_init_empty (&vstr); var_append_value_name (fctr->indep_var[0], - result->value[0], &vstr); + &result->value[0], &vstr); tab_text (tbl, 1, heading_rows + row_var_start + i * DESCRIPTIVE_ROWS, @@ -1549,11 +1442,11 @@ show_descriptives (const struct variable **dependent_var, TAB_LEFT, _("Mean")); - tab_text (tbl, n_cols - 4, - heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS, - TAB_LEFT | TAT_PRINTF, - _("%g%% Confidence Interval for Mean"), - cmd.n_cinterval[0]); + tab_text_format (tbl, n_cols - 4, + heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS, + TAB_LEFT, + _("%g%% Confidence Interval for Mean"), + cmd.n_cinterval[0]); tab_text (tbl, n_cols - 3, heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS, @@ -1566,9 +1459,8 @@ show_descriptives (const struct variable **dependent_var, _("Upper Bound")); tab_text (tbl, n_cols - 4, - heading_rows + row_var_start + 3 + i * DESCRIPTIVE_ROWS, - TAB_LEFT | TAT_PRINTF, - _("5%% Trimmed Mean")); + heading_rows + row_var_start + 3 + i * DESCRIPTIVE_ROWS, + TAB_LEFT, _("5% Trimmed Mean")); tab_text (tbl, n_cols - 4, heading_rows + row_var_start + 4 + i * DESCRIPTIVE_ROWS, @@ -1619,93 +1511,93 @@ show_descriptives (const struct variable **dependent_var, /* Now the statistics ... */ - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].mean, - 8, 2); + NULL); - tab_float (tbl, n_cols - 1, + tab_double (tbl, n_cols - 1, heading_rows + row_var_start + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].se_mean, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 1 + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].mean - t * result->metrics[v].se_mean, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 2 + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].mean + t * result->metrics[v].se_mean, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 3 + i * DESCRIPTIVE_ROWS, TAB_CENTER, - trimmed_mean_calculate ((struct trimmed_mean *) result->metrics[v].trimmed_mean), - 8, 2); + trimmed_mean_calculate (result->metrics[v].trimmed_mean), + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 4 + i * DESCRIPTIVE_ROWS, TAB_CENTER, percentile_calculate (result->metrics[v].quartiles[1], percentile_algorithm), - 8, 2); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 5 + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].variance, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 6 + i * DESCRIPTIVE_ROWS, TAB_CENTER, sqrt (result->metrics[v].variance), - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 10 + i * DESCRIPTIVE_ROWS, TAB_CENTER, percentile_calculate (result->metrics[v].quartiles[2], percentile_algorithm) - percentile_calculate (result->metrics[v].quartiles[0], percentile_algorithm), - 8, 2); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 11 + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].skewness, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 12 + i * DESCRIPTIVE_ROWS, TAB_CENTER, result->metrics[v].kurtosis, - 8, 3); + NULL); - tab_float (tbl, n_cols - 1, + tab_double (tbl, n_cols - 1, heading_rows + row_var_start + 11 + i * DESCRIPTIVE_ROWS, TAB_CENTER, calc_seskew (result->metrics[v].n), - 8, 3); + NULL); - tab_float (tbl, n_cols - 1, + tab_double (tbl, n_cols - 1, heading_rows + row_var_start + 12 + i * DESCRIPTIVE_ROWS, TAB_CENTER, calc_sekurt (result->metrics[v].n), - 8, 3); + NULL); { struct extremum *minimum, *maximum ; @@ -1716,23 +1608,23 @@ show_descriptives (const struct variable **dependent_var, maximum = ll_data (max_ll, struct extremum, ll); minimum = ll_data (min_ll, struct extremum, ll); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 7 + i * DESCRIPTIVE_ROWS, TAB_CENTER, minimum->value, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 8 + i * DESCRIPTIVE_ROWS, TAB_CENTER, maximum->value, - 8, 3); + NULL); - tab_float (tbl, n_cols - 2, + tab_double (tbl, n_cols - 2, heading_rows + row_var_start + 9 + i * DESCRIPTIVE_ROWS, TAB_CENTER, maximum->value - minimum->value, - 8, 3); + NULL); } } } @@ -1783,11 +1675,9 @@ show_extremes (const struct variable **dependent_var, n_cols = heading_columns + 2; - tbl = tab_create (n_cols, n_rows, 0); + tbl = tab_create (n_cols, n_rows); tab_headers (tbl, heading_columns, 0, heading_rows, 0); - tab_dim (tbl, tab_natural_dimensions); - /* Outline the box */ tab_box (tbl, TAL_2, TAL_2, @@ -1839,15 +1729,15 @@ show_extremes (const struct variable **dependent_var, for ( e = 1; e <= cmd.st_n; ++e ) { - tab_text (tbl, n_cols - 3, - heading_rows + row_var_start + row_result_start + e - 1, - TAB_RIGHT | TAT_PRINTF, - _("%d"), e); - - tab_text (tbl, n_cols - 3, - heading_rows + row_var_start + row_result_start + cmd.st_n + e - 1, - TAB_RIGHT | TAT_PRINTF, - _("%d"), e); + tab_text_format (tbl, n_cols - 3, + heading_rows + row_var_start + row_result_start + e - 1, + TAB_RIGHT, + "%d", e); + + tab_text_format (tbl, n_cols - 3, + heading_rows + row_var_start + row_result_start + cmd.st_n + e - 1, + TAB_RIGHT, + "%d", e); } @@ -1859,25 +1749,25 @@ show_extremes (const struct variable **dependent_var, while (weight-- > 0 && e < cmd.st_n) { - tab_float (tbl, n_cols - 1, + tab_double (tbl, n_cols - 1, heading_rows + row_var_start + row_result_start + cmd.st_n + e, TAB_RIGHT, minimum->value, - 8, 2); + NULL); - tab_float (tbl, n_cols - 2, - heading_rows + row_var_start + row_result_start + cmd.st_n + e, + tab_fixed (tbl, n_cols - 2, + heading_rows + row_var_start + + row_result_start + cmd.st_n + e, TAB_RIGHT, minimum->location, - 8, 0); + 10, 0); ++e; } min_ll = ll_next (min_ll); } - max_ll = ll_head (extrema_list (result->metrics[v].maxima)); for (e = 0; e < cmd.st_n;) { @@ -1886,18 +1776,20 @@ show_extremes (const struct variable **dependent_var, while (weight-- > 0 && e < cmd.st_n) { - tab_float (tbl, n_cols - 1, - heading_rows + row_var_start + row_result_start + e, + tab_double (tbl, n_cols - 1, + heading_rows + row_var_start + + row_result_start + e, TAB_RIGHT, maximum->value, - 8, 2); + NULL); - tab_float (tbl, n_cols - 2, - heading_rows + row_var_start + row_result_start + e, + tab_fixed (tbl, n_cols - 2, + heading_rows + row_var_start + + row_result_start + e, TAB_RIGHT, maximum->location, - 8, 0); + 10, 0); ++e; } @@ -1910,7 +1802,7 @@ show_extremes (const struct variable **dependent_var, struct string vstr; ds_init_empty (&vstr); var_append_value_name (fctr->indep_var[0], - result->value[0], &vstr); + &result->value[0], &vstr); tab_text (tbl, 1, heading_rows + row_var_start + row_result_start, @@ -1985,11 +1877,9 @@ show_percentiles (const struct variable **dependent_var, n_cols = heading_columns + n_percentiles; - tbl = tab_create (n_cols, n_rows, 0); + tbl = tab_create (n_cols, n_rows); tab_headers (tbl, heading_columns, 0, heading_rows, 0); - tab_dim (tbl, tab_natural_dimensions); - /* Outline the box */ tab_box (tbl, TAL_2, TAL_2, @@ -2042,7 +1932,7 @@ show_percentiles (const struct variable **dependent_var, struct string vstr; ds_init_empty (&vstr); var_append_value_name (fctr->indep_var[0], - result->value[0], &vstr); + &result->value[0], &vstr); tab_text (tbl, 1, heading_rows + row_var_start + i * PERCENTILE_ROWS, @@ -2068,18 +1958,17 @@ show_percentiles (const struct variable **dependent_var, tab_vline (tbl, TAL_1, n_cols - n_percentiles -1, heading_rows, n_rows - 1); - tukey_hinges_calculate ((struct tukey_hinges *) result->metrics[v].tukey_hinges, - hinges); + tukey_hinges_calculate (result->metrics[v].tukey_hinges, hinges); for (j = 0; j < n_percentiles; ++j) { double hinge = SYSMIS; - tab_float (tbl, n_cols - n_percentiles + j, + tab_double (tbl, n_cols - n_percentiles + j, heading_rows + row_var_start + i * PERCENTILE_ROWS, TAB_CENTER, percentile_calculate (result->metrics[v].ptl[j], percentile_algorithm), - 8, 2 + NULL ); if ( result->metrics[v].ptl[j]->ptile == 0.5) @@ -2090,11 +1979,11 @@ show_percentiles (const struct variable **dependent_var, hinge = hinges[2]; if ( hinge != SYSMIS) - tab_float (tbl, n_cols - n_percentiles + j, + tab_double (tbl, n_cols - n_percentiles + j, heading_rows + row_var_start + 1 + i * PERCENTILE_ROWS, TAB_CENTER, hinge, - 8, 2 + NULL ); } @@ -2108,11 +1997,10 @@ show_percentiles (const struct variable **dependent_var, for (i = 0 ; i < n_percentiles; ++i ) { - tab_text (tbl, n_cols - n_percentiles + i, 1, - TAB_CENTER | TAT_TITLE | TAT_PRINTF, - _("%g"), - subc_list_double_at (&percentile_list, i) - ); + tab_text_format (tbl, n_cols - n_percentiles + i, 1, + TAB_CENTER | TAT_TITLE, + _("%g"), + subc_list_double_at (&percentile_list, i)); } @@ -2145,13 +2033,13 @@ factor_to_string_concise (const struct xfactor *fctr, { if (fctr->indep_var[0]) { - var_append_value_name (fctr->indep_var[0], result->value[0], str); + var_append_value_name (fctr->indep_var[0], &result->value[0], str); if ( fctr->indep_var[1] ) { ds_put_cstr (str, ","); - var_append_value_name (fctr->indep_var[1], result->value[1], str); + var_append_value_name (fctr->indep_var[1], &result->value[1], str); ds_put_cstr (str, ")"); } @@ -2169,14 +2057,14 @@ factor_to_string (const struct xfactor *fctr, { ds_put_format (str, "(%s = ", var_get_name (fctr->indep_var[0])); - var_append_value_name (fctr->indep_var[0], result->value[0], str); + var_append_value_name (fctr->indep_var[0], &result->value[0], str); if ( fctr->indep_var[1] ) { ds_put_cstr (str, ","); ds_put_format (str, "%s = ", var_get_name (fctr->indep_var[1])); - var_append_value_name (fctr->indep_var[1], result->value[1], str); + var_append_value_name (fctr->indep_var[1], &result->value[1], str); } ds_put_cstr (str, ")"); }