X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Ffrequencies.c;fp=src%2Flanguage%2Fstats%2Ffrequencies.c;h=aa4eddfacc7831a9b8fab226f75f28e02a6b477a;hb=97fb55e07cac602cbca57ce8005de5c8a67a73cc;hp=254bda3ef709c8fd1c6785390ed583cd9211ca6c;hpb=6e44fb76d15ebc34122753b8a7a7d4a1b82bcb43;p=pspp diff --git a/src/language/stats/frequencies.c b/src/language/stats/frequencies.c index 254bda3ef7..aa4eddfacc 100644 --- a/src/language/stats/frequencies.c +++ b/src/language/stats/frequencies.c @@ -243,7 +243,7 @@ static void do_piechart(const struct frq_chart *pie, const struct freq_tab *frq_tab); static void do_barchart(const struct frq_chart *bar, - const struct variable *var, + const struct variable **var, const struct freq_tab *frq_tab); static void dump_statistics (const struct frq_proc *frq, @@ -264,7 +264,7 @@ compare_freq (const void *a_, const void *b_, const void *aux_) } else { - int cmp = value_compare_3way (&a->value, &b->value, aux->width); + int cmp = value_compare_3way (a->values, b->values, aux->width); return aux->ascending_value ? cmp : -cmp; } } @@ -317,11 +317,11 @@ dump_freq_table (const struct var_freqs *vf, const struct variable *wv) valid_percent = f->count / ft->valid_cases * 100.0; cum_total += valid_percent; - label = var_lookup_value_label (vf->var, &f->value); + label = var_lookup_value_label (vf->var, f->values); if (label != NULL) tab_text (t, 0, r, TAB_LEFT, label); - tab_value (t, 1, r, TAB_NONE, &f->value, vf->var, NULL); + tab_value (t, 1, r, TAB_NONE, f->values, vf->var, NULL); tab_double (t, 2, r, TAB_NONE, f->count, NULL, RC_WEIGHT); tab_double (t, 3, r, TAB_NONE, percent, NULL, RC_OTHER); tab_double (t, 4, r, TAB_NONE, valid_percent, NULL, RC_OTHER); @@ -334,11 +334,11 @@ dump_freq_table (const struct var_freqs *vf, const struct variable *wv) cum_freq += f->count; - label = var_lookup_value_label (vf->var, &f->value); + label = var_lookup_value_label (vf->var, f->values); if (label != NULL) tab_text (t, 0, r, TAB_LEFT, label); - tab_value (t, 1, r, TAB_NONE, &f->value, vf->var, NULL); + tab_value (t, 1, r, TAB_NONE, f->values, vf->var, NULL); tab_double (t, 2, r, TAB_NONE, f->count, NULL, RC_WEIGHT); tab_double (t, 3, r, TAB_NONE, f->count / ft->total_cases * 100.0, NULL, RC_OTHER); @@ -399,15 +399,15 @@ calc_percentiles (const struct frq_proc *frq, const struct var_freqs *vf) break; if (tp + 1 < rank || f + 1 >= ft->missing) - pc->value = f->value.f; + pc->value = f->values[0].f; else - pc->value = calc_percentile (pc->p, W, f->value.f, f[1].value.f); + pc->value = calc_percentile (pc->p, W, f->values[0].f, f[1].values[0].f); } } for (; percentile_idx < frq->n_percentiles; percentile_idx++) { struct percentile *pc = &frq->percentiles[percentile_idx]; - pc->value = ft->valid[ft->n_valid - 1].value.f; + pc->value = ft->valid[ft->n_valid - 1].values[0].f; } } @@ -419,7 +419,7 @@ not_missing (const void *f_, const void *v_) const struct freq *f = f_; const struct variable *v = v_; - return !var_is_value_missing (v, &f->value, MV_ANY); + return !var_is_value_missing (v, f->values, MV_ANY); } @@ -569,7 +569,7 @@ postcalc (struct frq_proc *frq, const struct dataset *ds) do_piechart(frq->pie, vf->var, &vf->tab); if (frq->bar) - do_barchart(frq->bar, vf->var, &vf->tab); + do_barchart(frq->bar, &vf->var, &vf->tab); cleanup_freq_tab (vf); } @@ -588,7 +588,7 @@ cmd_frequencies (struct lexer *lexer, struct dataset *ds) double pie_min = -DBL_MAX; double pie_max = DBL_MAX; - bool pie_missing = false; + bool pie_missing = true; double bar_min = -DBL_MAX; double bar_max = DBL_MAX; @@ -798,7 +798,6 @@ cmd_frequencies (struct lexer *lexer, struct dataset *ds) { if (lex_match_id (lexer, "TABLE")) { - } else if (lex_match_id (lexer, "NOTABLE")) { @@ -1141,7 +1140,7 @@ cmd_frequencies (struct lexer *lexer, struct dataset *ds) frq.bar = xmalloc (sizeof *frq.bar); frq.bar->x_min = bar_min; frq.bar->x_max = bar_max; - frq.bar->include_missing = true; + frq.bar->include_missing = false; frq.bar->y_scale = bar_freq ? FRQ_FREQ : FRQ_PERCENT; } @@ -1281,10 +1280,10 @@ freq_tab_to_hist (const struct frq_proc *frq, const struct freq_tab *ft, for (i = 0; i < ft->n_valid; i++) { const struct freq *f = &ft->valid[i]; - if (chart_includes_value (frq->hist, var, &f->value)) + if (chart_includes_value (frq->hist, var, f->values)) { - x_min = MIN (x_min, f->value.f); - x_max = MAX (x_max, f->value.f); + x_min = MIN (x_min, f->values[0].f); + x_max = MAX (x_max, f->values[0].f); valid_freq += f->count; } } @@ -1308,83 +1307,118 @@ freq_tab_to_hist (const struct frq_proc *frq, const struct freq_tab *ft, for (i = 0; i < ft->n_valid; i++) { const struct freq *f = &ft->valid[i]; - if (chart_includes_value (frq->hist, var, &f->value)) - histogram_add (histogram, f->value.f, f->count); + if (chart_includes_value (frq->hist, var, f->values)) + histogram_add (histogram, f->values[0].f, f->count); } return histogram; } -static int -add_slice (const struct frq_chart *pie, const struct freq *freq, - const struct variable *var, struct slice *slice) + +/* Allocate an array of struct freqs and fill them from the data in FRQ_TAB, + according to the parameters of CATCHART + N_SLICES will contain the number of slices allocated. + The caller is responsible for freeing slices +*/ +static struct freq * +pick_cat_counts (const struct frq_chart *catchart, + const struct freq_tab *frq_tab, + int *n_slicesp) { - if (chart_includes_value (pie, var, &freq->value)) + int n_slices = 0; + int i; + struct freq *slices = xnmalloc (frq_tab->n_valid + frq_tab->n_missing, sizeof *slices); + + for (i = 0; i < frq_tab->n_valid; i++) + { + const struct freq *f = &frq_tab->valid[i]; + if (f->count > catchart->x_max) + continue; + + if (f->count < catchart->x_min) + continue; + + slices[n_slices] = *f; + + n_slices++; + } + + if (catchart->include_missing) { - ds_init_empty (&slice->label); - var_append_value_name (var, &freq->value, &slice->label); - slice->magnitude = freq->count; - return 1; + for (i = 0; i < frq_tab->n_missing; i++) + { + const struct freq *f = &frq_tab->missing[i]; + slices[n_slices].count += f->count; + + if (i == 0) + slices[n_slices].values[0] = f->values[0]; + } + + if (frq_tab->n_missing > 0) + n_slices++; } - else - return 0; + + *n_slicesp = n_slices; + return slices; } -/* Allocate an array of slices and fill them from the data in frq_tab - n_slices will contain the number of slices allocated. + +/* Allocate an array of struct freqs and fill them from the data in FRQ_TAB, + according to the parameters of CATCHART + N_SLICES will contain the number of slices allocated. The caller is responsible for freeing slices */ -static struct slice * -freq_tab_to_slice_array(const struct frq_chart *catchart, - const struct freq_tab *frq_tab, - const struct variable *var, - int *n_slicesp) +static struct freq ** +pick_cat_counts_ptr (const struct frq_chart *catchart, + const struct freq_tab *frq_tab, + int *n_slicesp) { - struct slice *slices; - int n_slices; + int n_slices = 0; int i; - double total = 0; - - slices = xnmalloc (frq_tab->n_valid + frq_tab->n_missing, sizeof *slices); - n_slices = 0; - + struct freq **slices = xnmalloc (frq_tab->n_valid + frq_tab->n_missing, sizeof *slices); for (i = 0; i < frq_tab->n_valid; i++) { - const struct freq *f = &frq_tab->valid[i]; - total += f->count; + struct freq *f = &frq_tab->valid[i]; if (f->count > catchart->x_max) continue; if (f->count < catchart->x_min) continue; - - n_slices += add_slice (catchart, f, var, &slices[n_slices]); + + slices[n_slices] = f; + + n_slices++; } - if (catchart->y_scale == FRQ_PERCENT) - for (i = 0; i < frq_tab->n_valid; i++) - { - slices[i].magnitude /= total; - slices[i].magnitude *= 100.00; - } - - for (i = 0; i < frq_tab->n_missing; i++) - n_slices += add_slice (catchart, &frq_tab->missing[i], var, &slices[n_slices]); + if (catchart->include_missing) + { + for (i = 0; i < frq_tab->n_missing; i++) + { + const struct freq *f = &frq_tab->missing[i]; + if (i == 0) + { + slices[n_slices] = xmalloc (sizeof (struct freq)); + slices[n_slices]->values[0] = f->values[0]; + } + + slices[n_slices]->count += f->count; + + } + } *n_slicesp = n_slices; return slices; } + static void do_piechart(const struct frq_chart *pie, const struct variable *var, const struct freq_tab *frq_tab) { - struct slice *slices; - int n_slices, i; - - slices = freq_tab_to_slice_array (pie, frq_tab, var, &n_slices); + int n_slices; + struct freq *slices = pick_cat_counts (pie, frq_tab, &n_slices); if (n_slices < 2) msg (SW, _("Omitting pie chart for %s, which has only %d unique values."), @@ -1393,29 +1427,22 @@ do_piechart(const struct frq_chart *pie, const struct variable *var, msg (SW, _("Omitting pie chart for %s, which has over 50 unique values."), var_get_name (var)); else - chart_item_submit (piechart_create (var_to_string(var), slices, n_slices)); + chart_item_submit (piechart_create (var, slices, n_slices)); - for (i = 0; i < n_slices; i++) - ds_destroy (&slices[i].label); free (slices); } static void -do_barchart(const struct frq_chart *bar, const struct variable *var, +do_barchart(const struct frq_chart *bar, const struct variable **var, const struct freq_tab *frq_tab) { - struct slice *slices; - int n_slices, i; - - slices = freq_tab_to_slice_array (bar, frq_tab, var, &n_slices); + int n_slices; + struct freq **slices = pick_cat_counts_ptr (bar, frq_tab, &n_slices); - chart_item_submit (barchart_create (var_to_string (var), + chart_item_submit (barchart_create (var, 1, (bar->y_scale == FRQ_FREQ) ? _("Count") : _("Percent"), slices, n_slices)); - - for (i = 0; i < n_slices; i++) - ds_destroy (&slices[i].label); free (slices); } @@ -1438,7 +1465,7 @@ calc_stats (const struct var_freqs *vf, double d[FRQ_ST_count]) if (most_often < f->count) { most_often = f->count; - X_mode = f->value.f; + X_mode = f->values[0].f; } else if (most_often == f->count) { @@ -1451,16 +1478,16 @@ calc_stats (const struct var_freqs *vf, double d[FRQ_ST_count]) /* Calculate moments. */ m = moments_create (MOMENT_KURTOSIS); for (f = ft->valid; f < ft->missing; f++) - moments_pass_one (m, f->value.f, f->count); + moments_pass_one (m, f->values[0].f, f->count); for (f = ft->valid; f < ft->missing; f++) - moments_pass_two (m, f->value.f, f->count); + moments_pass_two (m, f->values[0].f, f->count); moments_calculate (m, NULL, &d[FRQ_ST_MEAN], &d[FRQ_ST_VARIANCE], &d[FRQ_ST_SKEWNESS], &d[FRQ_ST_KURTOSIS]); moments_destroy (m); /* Formulae below are taken from _SPSS Statistical Algorithms_. */ - d[FRQ_ST_MINIMUM] = ft->valid[0].value.f; - d[FRQ_ST_MAXIMUM] = ft->valid[ft->n_valid - 1].value.f; + d[FRQ_ST_MINIMUM] = ft->valid[0].values[0].f; + d[FRQ_ST_MAXIMUM] = ft->valid[ft->n_valid - 1].values[0].f; d[FRQ_ST_MODE] = X_mode; d[FRQ_ST_RANGE] = d[FRQ_ST_MAXIMUM] - d[FRQ_ST_MINIMUM]; d[FRQ_ST_SUM] = d[FRQ_ST_MEAN] * W;