#include <stdlib.h>
#include <gsl/gsl_histogram.h>
-#include <data/case.h>
-#include <data/casegrouper.h>
-#include <data/casereader.h>
-#include <data/dictionary.h>
-#include <data/format.h>
-#include <data/procedure.h>
-#include <data/settings.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/array.h>
-#include <libpspp/bit-vector.h>
-#include <libpspp/compiler.h>
-#include <libpspp/hash.h>
-#include <libpspp/message.h>
-#include <libpspp/misc.h>
-#include <libpspp/pool.h>
-#include <libpspp/str.h>
-#include <math/histogram.h>
-#include <math/moments.h>
-#include <output/chart-item.h>
-#include <output/charts/piechart.h>
-#include <output/charts/plot-hist.h>
-#include <output/tab.h>
-
-#include "freq.h"
-
-#include "minmax.h"
-#include "xalloc.h"
+#include "data/case.h"
+#include "data/casegrouper.h"
+#include "data/casereader.h"
+#include "data/dictionary.h"
+#include "data/format.h"
+#include "data/procedure.h"
+#include "data/settings.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 "language/stats/freq.h"
+#include "libpspp/array.h"
+#include "libpspp/bit-vector.h"
+#include "libpspp/compiler.h"
+#include "libpspp/hmap.h"
+#include "libpspp/message.h"
+#include "libpspp/misc.h"
+#include "libpspp/pool.h"
+#include "libpspp/str.h"
+#include "math/histogram.h"
+#include "math/moments.h"
+#include "output/chart-item.h"
+#include "output/charts/piechart.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)
/* Statistics. */
enum
{
- frq_mean = 0, frq_semean, frq_median, frq_mode, frq_stddev, frq_variance,
- frq_kurt, frq_sekurt, frq_skew, frq_seskew, frq_range, frq_min, frq_max,
- frq_sum, frq_n_stats
+ FRQ_MEAN, FRQ_SEMEAN, FRQ_MEDIAN, FRQ_MODE, FRQ_STDDEV, FRQ_VARIANCE,
+ FRQ_KURT, FRQ_SEKURT, FRQ_SKEW, FRQ_SESKEW, FRQ_RANGE, FRQ_MIN, FRQ_MAX,
+ FRQ_SUM, FRQ_N_STATS
};
/* Description of a statistic. */
};
/* Table of statistics, indexed by dsc_*. */
-static const struct frq_info st_name[frq_n_stats + 1] =
+static const struct frq_info st_name[FRQ_N_STATS + 1] =
{
{FRQ_ST_MEAN, N_("Mean")},
{FRQ_ST_SEMEAN, N_("S.E. Mean")},
};
-static void add_percentile (double x, bool show);
-
static struct percentile *percentiles;
static int n_percentiles, n_show_percentiles;
/* Groups of statistics. */
#define BI BIT_INDEX
-#define frq_default \
- (BI (frq_mean) | BI (frq_stddev) | BI (frq_min) | BI (frq_max))
-#define frq_all \
- (BI (frq_sum) | BI(frq_min) | BI(frq_max) \
- | BI(frq_mean) | BI(frq_semean) | BI(frq_stddev) \
- | BI(frq_variance) | BI(frq_kurt) | BI(frq_sekurt) \
- | BI(frq_skew) | BI(frq_seskew) | BI(frq_range) \
- | BI(frq_range) | BI(frq_mode) | BI(frq_median))
+#define FRQ_DEFAULT \
+ (BI (FRQ_MEAN) | BI (FRQ_STDDEV) | BI (FRQ_MIN) | BI (FRQ_MAX))
+#define FRQ_ALL \
+ (BI (FRQ_SUM) | BI(FRQ_MIN) | BI(FRQ_MAX) \
+ | BI(FRQ_MEAN) | BI(FRQ_SEMEAN) | BI(FRQ_STDDEV) \
+ | BI(FRQ_VARIANCE) | BI(FRQ_KURT) | BI(FRQ_SEKURT) \
+ | BI(FRQ_SKEW) | BI(FRQ_SESKEW) | BI(FRQ_RANGE) \
+ | BI(FRQ_RANGE) | BI(FRQ_MODE) | BI(FRQ_MEDIAN))
/* Statistics; number of statistics. */
static unsigned long stats;
/* Parsed command. */
static struct cmd_frequencies cmd;
-/* Variables for which to calculate statistics. */
-static size_t n_variables;
-static const struct variable **v_variables;
-
-/* Pools. */
-static struct pool *data_pool; /* For per-SPLIT FILE group data. */
-static struct pool *syntax_pool; /* For syntax-related data. */
-
/* Frequency tables. */
/* Entire frequency table. */
struct freq_tab
{
- struct hsh_table *data; /* Undifferentiated data. */
- struct freq_mutable *valid; /* Valid freqs. */
+ struct hmap data; /* Hash table for accumulating counts. */
+ struct freq *valid; /* Valid freqs. */
int n_valid; /* Number of total freqs. */
- const struct dictionary *dict; /* The dict from whence entries in the table
- come */
+ const struct dictionary *dict; /* Source of entries in the table. */
- struct freq_mutable *missing; /* Missing freqs. */
+ struct freq *missing; /* Missing freqs. */
int n_missing; /* Number of missing freqs. */
/* Statistics. */
/* Per-variable frequency data. */
struct var_freqs
{
+ struct variable *var;
+
/* Freqency table. */
struct freq_tab tab; /* Frequencies table to use. */
double *groups; /* Groups. */
/* Statistics. */
- double stat[frq_n_stats];
+ double stat[FRQ_N_STATS];
/* Variable attributes. */
int width;
struct fmt_spec print;
};
-static inline struct var_freqs *
-get_var_freqs (const struct variable *v)
-{
- return var_get_aux (v);
-}
+struct frq_proc
+ {
+ struct pool *pool;
+
+ struct var_freqs *vars;
+ size_t n_vars;
+ };
static void determine_charts (void);
-static void calc_stats (const struct variable *v, double d[frq_n_stats]);
+static void calc_stats (const struct var_freqs *v, double d[FRQ_N_STATS]);
-static void precalc (struct casereader *, struct dataset *);
-static void calc (const struct ccase *, const struct dataset *);
-static void postcalc (const struct dataset *);
+static void precalc (struct frq_proc *, struct casereader *, struct dataset *);
+static void calc (struct frq_proc *, const struct ccase *,
+ const struct dataset *);
+static void postcalc (struct frq_proc *, const struct dataset *);
-static void postprocess_freq_tab (const struct variable *);
-static void dump_freq_table (const struct variable *, const struct variable *);
-static void dump_statistics (const struct variable *, const struct variable *);
-static void cleanup_freq_tab (const struct variable *);
+static void postprocess_freq_tab (struct var_freqs *);
+static void dump_freq_table (const struct var_freqs *,
+ const struct variable *weight_var);
+static void dump_statistics (const struct var_freqs *,
+ const struct variable *weight_var);
+static void cleanup_freq_tab (struct var_freqs *);
-static hsh_compare_func compare_value_numeric_a, compare_value_alpha_a;
-static hsh_compare_func compare_value_numeric_d, compare_value_alpha_d;
-static hsh_compare_func compare_freq_numeric_a, compare_freq_alpha_a;
-static hsh_compare_func compare_freq_numeric_d, compare_freq_alpha_d;
+static algo_compare_func compare_value_numeric_a, compare_value_alpha_a;
+static algo_compare_func compare_value_numeric_d, compare_value_alpha_d;
+static algo_compare_func compare_freq_numeric_a, compare_freq_alpha_a;
+static algo_compare_func compare_freq_numeric_d, compare_freq_alpha_d;
+static void add_percentile (struct frq_proc *, double x, bool show);
static void do_piechart(const struct variable *var,
const struct freq_tab *frq_tab);
\f
/* Parser and outline. */
-static int internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds);
-
int
cmd_frequencies (struct lexer *lexer, struct dataset *ds)
{
- int result;
-
- syntax_pool = pool_create ();
- result = internal_cmd_frequencies (lexer, ds);
- pool_destroy (syntax_pool);
- syntax_pool=0;
- pool_destroy (data_pool);
- data_pool=0;
- free (v_variables);
- v_variables=0;
- return result;
-}
-
-static int
-internal_cmd_frequencies (struct lexer *lexer, struct dataset *ds)
-{
+ struct frq_proc frq;
struct casegrouper *grouper;
struct casereader *input, *group;
bool ok;
n_show_percentiles = 0;
percentiles = NULL;
- n_variables = 0;
- v_variables = NULL;
+ frq.pool = pool_create ();
+ frq.vars = NULL;
+ frq.n_vars = 0;
- if (!parse_frequencies (lexer, ds, &cmd, NULL))
- return CMD_FAILURE;
+ if (!parse_frequencies (lexer, ds, &cmd, &frq))
+ {
+ pool_destroy (frq.pool);
+ return CMD_FAILURE;
+ }
/* Figure out statistics to calculate. */
stats = 0;
if (cmd.a_statistics[FRQ_ST_DEFAULT] || !cmd.sbc_statistics)
- stats |= frq_default;
+ stats |= FRQ_DEFAULT;
if (cmd.a_statistics[FRQ_ST_ALL])
- stats |= frq_all;
+ stats |= FRQ_ALL;
if (cmd.sort != FRQ_AVALUE && cmd.sort != FRQ_DVALUE)
- stats &= ~BIT_INDEX (frq_median);
- for (i = 0; i < frq_n_stats; i++)
+ stats &= ~BIT_INDEX (FRQ_MEDIAN);
+ for (i = 0; i < FRQ_N_STATS; i++)
if (cmd.a_statistics[st_name[i].st_indx])
stats |= BIT_INDEX (i);
- if (stats & frq_kurt)
- stats |= BIT_INDEX (frq_sekurt);
- if (stats & frq_skew)
- stats |= BIT_INDEX (frq_seskew);
+ if (stats & FRQ_KURT)
+ stats |= BIT_INDEX (FRQ_SEKURT);
+ if (stats & FRQ_SKEW)
+ stats |= BIT_INDEX (FRQ_SESKEW);
/* Calculate n_stats. */
n_stats = 0;
- for (i = 0; i < frq_n_stats; i++)
+ for (i = 0; i < FRQ_N_STATS; i++)
if ((stats & BIT_INDEX (i)))
n_stats++;
int pl;
subc_list_double *ptl_list = &cmd.dl_percentiles[i];
for ( pl = 0 ; pl < subc_list_double_count(ptl_list); ++pl)
- add_percentile (subc_list_double_at(ptl_list, pl) / 100.0, true);
+ add_percentile (&frq, subc_list_double_at(ptl_list, pl) / 100.0,
+ true);
}
}
if ( cmd.sbc_ntiles )
{
int j;
for (j = 0; j <= cmd.n_ntiles[i]; ++j )
- add_percentile (j / (double) cmd.n_ntiles[i], true);
+ add_percentile (&frq, j / (double) cmd.n_ntiles[i], true);
}
}
- if (stats & BIT_INDEX (frq_median))
+ if (stats & BIT_INDEX (FRQ_MEDIAN))
{
/* Treat the median as the 50% percentile.
We output it in the percentiles table as "50 (Median)." */
- add_percentile (0.5, true);
- stats &= ~BIT_INDEX (frq_median);
+ add_percentile (&frq, 0.5, true);
+ stats &= ~BIT_INDEX (FRQ_MEDIAN);
n_stats--;
}
if (cmd.sbc_histogram)
{
- add_percentile (0.25, false);
- add_percentile (0.75, false);
+ add_percentile (&frq, 0.25, false);
+ add_percentile (&frq, 0.75, false);
}
/* Do it! */
{
struct ccase *c;
- precalc (group, ds);
+ precalc (&frq, group, ds);
for (; (c = casereader_read (group)) != NULL; case_unref (c))
- calc (c, ds);
- postcalc (ds);
+ calc (&frq, c, ds);
+ postcalc (&frq, ds);
}
ok = casegrouper_destroy (grouper);
ok = proc_commit (ds) && ok;
free_frequencies(&cmd);
+ pool_destroy (frq.pool);
+ free (frq.vars);
+
return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
}
/* Add data from case C to the frequency table. */
static void
-calc (const struct ccase *c, const struct dataset *ds)
+calc (struct frq_proc *frq, const struct ccase *c, const struct dataset *ds)
{
double weight = dict_get_case_weight (dataset_dict (ds), c, NULL);
size_t i;
- for (i = 0; i < n_variables; i++)
+ for (i = 0; i < frq->n_vars; i++)
{
- const struct variable *v = v_variables[i];
- const union value *val = case_data (c, v);
- struct var_freqs *vf = get_var_freqs (v);
- struct freq_tab *ft = &vf->tab;
-
- struct freq_mutable target;
- struct freq_mutable **fpp;
+ struct var_freqs *vf = &frq->vars[i];
+ const union value *value = case_data (c, vf->var);
+ size_t hash = value_hash (value, vf->width, 0);
+ struct freq *f;
- target.value = *val;
- fpp = (struct freq_mutable **) hsh_probe (ft->data, &target);
+ f = freq_hmap_search (&vf->tab.data, value, vf->width, hash);
+ if (f == NULL)
+ f = freq_hmap_insert (&vf->tab.data, value, vf->width, hash);
- if (*fpp != NULL)
- (*fpp)->count += weight;
- else
- {
- struct freq_mutable *fp = pool_alloc (data_pool, sizeof *fp);
- fp->count = weight;
- value_init_pool (data_pool, &fp->value, vf->width);
- value_copy (&fp->value, val, vf->width);
- *fpp = fp;
- }
+ f->count += weight;
}
}
/* Prepares each variable that is the target of FREQUENCIES by setting
up its hash table. */
static void
-precalc (struct casereader *input, struct dataset *ds)
+precalc (struct frq_proc *frq, struct casereader *input, struct dataset *ds)
{
struct ccase *c;
size_t i;
case_unref (c);
}
- pool_destroy (data_pool);
- data_pool = pool_create ();
-
- for (i = 0; i < n_variables; i++)
- {
- const struct variable *v = v_variables[i];
- struct freq_tab *ft = &get_var_freqs (v)->tab;
-
- ft->data = hsh_create (16, compare_freq, hash_freq, NULL, v);
- }
+ for (i = 0; i < frq->n_vars; i++)
+ hmap_init (&frq->vars[i].tab.data);
}
/* Finishes up with the variables after frequencies have been
calculated. Displays statistics, percentiles, ... */
static void
-postcalc (const struct dataset *ds)
+postcalc (struct frq_proc *frq, const struct dataset *ds)
{
const struct dictionary *dict = dataset_dict (ds);
const struct variable *wv = dict_get_weight (dict);
size_t i;
- for (i = 0; i < n_variables; i++)
+ for (i = 0; i < frq->n_vars; i++)
{
- const struct variable *v = v_variables[i];
- struct var_freqs *vf = get_var_freqs (v);
- struct freq_tab *ft = &vf->tab;
+ struct var_freqs *vf = &frq->vars[i];
int n_categories;
- postprocess_freq_tab (v);
+ postprocess_freq_tab (vf);
/* Frequencies tables. */
- n_categories = ft->n_valid + ft->n_missing;
+ n_categories = vf->tab.n_valid + vf->tab.n_missing;
if (cmd.table == FRQ_TABLE
|| (cmd.table == FRQ_LIMIT && n_categories <= cmd.limit))
- dump_freq_table (v, wv);
+ dump_freq_table (vf, wv);
/* Statistics. */
if (n_stats)
- dump_statistics (v, wv);
+ dump_statistics (vf, wv);
- if (cmd.sbc_histogram && var_is_numeric (v) && ft->n_valid > 0)
+ if (cmd.sbc_histogram && var_is_numeric (vf->var) && vf->tab.n_valid > 0)
{
- double d[frq_n_stats];
+ double d[FRQ_N_STATS];
struct histogram *histogram;
- calc_stats (v, d);
+ calc_stats (vf, d);
- histogram = freq_tab_to_hist (ft, v);
+ histogram = freq_tab_to_hist (&vf->tab, vf->var);
chart_item_submit (histogram_chart_create (
- histogram->gsl_hist, var_to_string(v),
+ histogram->gsl_hist, var_to_string(vf->var),
vf->tab.valid_cases,
- d[frq_mean],
- d[frq_stddev],
+ d[FRQ_MEAN],
+ d[FRQ_STDDEV],
hist.draw_normal));
statistic_destroy (&histogram->parent);
}
if (cmd.sbc_piechart)
- do_piechart(v_variables[i], ft);
+ do_piechart(vf->var, &vf->tab);
- cleanup_freq_tab (v);
+ cleanup_freq_tab (vf);
}
}
/* Returns the comparison function that should be used for
sorting a frequency table by FRQ_SORT using VAL_TYPE
values. */
-static hsh_compare_func *
+static algo_compare_func *
get_freq_comparator (int frq_sort, enum val_type val_type)
{
bool is_numeric = val_type == VAL_NUMERIC;
}
}
-/* Returns true iff the value in struct freq_mutable F is non-missing
+/* Returns true iff the value in struct freq F is non-missing
for variable V. */
static bool
not_missing (const void *f_, const void *v_)
{
- const struct freq_mutable *f = f_;
+ const struct freq *f = f_;
const struct variable *v = v_;
return !var_is_value_missing (v, &f->value, MV_ANY);
/* Summarizes the frequency table data for variable V. */
static void
-postprocess_freq_tab (const struct variable *v)
+postprocess_freq_tab (struct var_freqs *vf)
{
- hsh_compare_func *compare;
- struct freq_tab *ft;
+ struct freq_tab *ft = &vf->tab;
+ algo_compare_func *compare;
size_t count;
- void *const *data;
- struct freq_mutable *freqs, *f;
+ struct freq *freqs, *f;
size_t i;
- ft = &get_var_freqs (v)->tab;
- compare = get_freq_comparator (cmd.sort, var_get_type (v));
-
/* Extract data from hash table. */
- count = hsh_count (ft->data);
- data = hsh_data (ft->data);
-
- /* Copy dereferenced data into freqs. */
- freqs = xnmalloc (count, sizeof *freqs);
- for (i = 0; i < count; i++)
- {
- struct freq_mutable *f = data[i];
- freqs[i] = *f;
- }
+ count = hmap_count (&ft->data);
+ freqs = freq_hmap_extract (&ft->data);
/* Put data into ft. */
ft->valid = freqs;
- ft->n_valid = partition (freqs, count, sizeof *freqs, not_missing, v);
+ ft->n_valid = partition (freqs, count, sizeof *freqs, not_missing, vf->var);
ft->missing = freqs + ft->n_valid;
ft->n_missing = count - ft->n_valid;
/* Sort data. */
- sort (ft->valid, ft->n_valid, sizeof *ft->valid, compare, v);
- sort (ft->missing, ft->n_missing, sizeof *ft->missing, compare, v);
+ compare = get_freq_comparator (cmd.sort, var_get_type (vf->var));
+ sort (ft->valid, ft->n_valid, sizeof *ft->valid, compare, vf);
+ sort (ft->missing, ft->n_missing, sizeof *ft->missing, compare, vf);
/* Summary statistics. */
ft->valid_cases = 0.0;
/* Frees the frequency table for variable V. */
static void
-cleanup_freq_tab (const struct variable *v)
+cleanup_freq_tab (struct var_freqs *vf)
{
- struct freq_tab *ft = &get_var_freqs (v)->tab;
- free (ft->valid);
- hsh_destroy (ft->data);
+ free (vf->tab.valid);
+ freq_hmap_destroy (&vf->tab.data, vf->width);
}
-/* Parses the VARIABLES subcommand, adding to
- {n_variables,v_variables}. */
+/* Parses the VARIABLES subcommand. */
static int
-frq_custom_variables (struct lexer *lexer, struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
+frq_custom_variables (struct lexer *lexer, struct dataset *ds,
+ struct cmd_frequencies *cmd UNUSED, void *frq_ UNUSED)
{
- size_t old_n_variables = n_variables;
+ struct frq_proc *frq = frq_;
+ struct variable **vars;
+ size_t n_vars;
size_t i;
lex_match (lexer, '=');
- if (lex_token (lexer) != T_ALL && (lex_token (lexer) != T_ID
- || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL))
+ if (lex_token (lexer) != T_ALL
+ && (lex_token (lexer) != T_ID
+ || dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) == NULL))
return 2;
- if (!parse_variables_const (lexer, dataset_dict (ds), &v_variables, &n_variables,
- PV_APPEND | PV_NO_SCRATCH))
+ /* Get list of current variables, to avoid duplicates. */
+ vars = xmalloc (frq->n_vars * sizeof *vars);
+ n_vars = frq->n_vars;
+ for (i = 0; i < frq->n_vars; i++)
+ vars[i] = frq->vars[i].var;
+
+ if (!parse_variables (lexer, dataset_dict (ds), &vars, &n_vars,
+ PV_APPEND | PV_NO_SCRATCH))
return 0;
- for (i = old_n_variables; i < n_variables; i++)
+ frq->vars = xrealloc (frq->vars, n_vars * sizeof *frq->vars);
+ for (i = frq->n_vars; i < n_vars; i++)
{
- const struct variable *v = v_variables[i];
- struct var_freqs *vf;
+ struct variable *var = vars[i];
+ struct var_freqs *vf = &frq->vars[i];
- if (var_get_aux (v) != NULL)
- {
- msg (SE, _("Variable %s specified multiple times on VARIABLES "
- "subcommand."), var_get_name (v));
- return 0;
- }
- vf = var_attach_aux (v, xmalloc (sizeof *vf), var_dtor_free);
+ vf->var = var;
vf->tab.valid = vf->tab.missing = NULL;
vf->tab.dict = dataset_dict (ds);
vf->n_groups = 0;
vf->groups = NULL;
- vf->width = var_get_width (v);
- vf->print = *var_get_print_format (v);
+ vf->width = var_get_width (var);
+ vf->print = *var_get_print_format (var);
}
+ frq->n_vars = n_vars;
+
+ free (vars);
+
return 1;
}
/* Parses the GROUPED subcommand, setting the n_grouped, grouped
fields of specified variables. */
static int
-frq_custom_grouped (struct lexer *lexer, struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *aux UNUSED)
+frq_custom_grouped (struct lexer *lexer, struct dataset *ds, struct cmd_frequencies *cmd UNUSED, void *frq_ UNUSED)
{
+ struct frq_proc *frq = frq_;
+
lex_match (lexer, '=');
if ((lex_token (lexer) == T_ID && dict_lookup_var (dataset_dict (ds), lex_tokid (lexer)) != NULL)
|| lex_token (lexer) == T_ID)
if (nl >= ml)
{
ml += 16;
- dl = pool_nrealloc (syntax_pool, dl, ml, sizeof *dl);
+ dl = pool_nrealloc (frq->pool, dl, ml, sizeof *dl);
}
dl[nl++] = lex_tokval (lexer);
lex_get (lexer);
}
for (i = 0; i < n; i++)
- if (var_get_aux (v[i]) == NULL)
+ {
+ size_t j;
+
+ for (j = 0; j < frq->n_vars; j++)
+ {
+ struct var_freqs *vf = &frq->vars[j];
+ if (vf->var == v[i])
+ {
+ if (vf->groups != NULL)
+ msg (SE, _("Variables %s specified multiple times on "
+ "GROUPED subcommand."), var_get_name (v[i]));
+ else
+ {
+ vf->n_groups = nl;
+ vf->groups = dl;
+ }
+ goto found;
+ }
+ }
msg (SE, _("Variables %s specified on GROUPED but not on "
"VARIABLES."), var_get_name (v[i]));
- else
- {
- struct var_freqs *vf = get_var_freqs (v[i]);
-
- if (vf->groups != NULL)
- msg (SE, _("Variables %s specified multiple times on GROUPED "
- "subcommand."), var_get_name (v[i]));
- else
- {
- vf->n_groups = nl;
- vf->groups = dl;
- }
- }
+
+ found:;
+ }
+
free (v);
if (!lex_match (lexer, '/'))
break;
order. If SHOW is true, the percentile will be shown in the statistics
box, otherwise it will be hidden. */
static void
-add_percentile (double x, bool show)
+add_percentile (struct frq_proc *frq, double x, bool show)
{
int i;
if (i >= n_percentiles || x != percentiles[i].p)
{
- percentiles = pool_nrealloc (syntax_pool, percentiles,
+ percentiles = pool_nrealloc (frq->pool, percentiles,
n_percentiles + 1, sizeof *percentiles);
insert_element (percentiles, n_percentiles, sizeof *percentiles, i);
percentiles[i].p = x;
/* Ascending numeric compare of values. */
static int
-compare_value_numeric_a (const void *a_, const void *b_, const void *aux UNUSED)
+compare_value_numeric_a (const void *a_, const void *b_,
+ const void *vf_ UNUSED)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
+ const struct freq *a = a_;
+ const struct freq *b = b_;
if (a->value.f > b->value.f)
return 1;
/* Ascending string compare of values. */
static int
-compare_value_alpha_a (const void *a_, const void *b_, const void *v_)
+compare_value_alpha_a (const void *a_, const void *b_, const void *vf_)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
- const struct variable *v = v_;
- struct var_freqs *vf = get_var_freqs (v);
+ const struct freq *a = a_;
+ const struct freq *b = b_;
+ const struct var_freqs *vf = vf_;
return value_compare_3way (&a->value, &b->value, vf->width);
}
/* Descending numeric compare of values. */
static int
-compare_value_numeric_d (const void *a, const void *b, const void *aux UNUSED)
+compare_value_numeric_d (const void *a, const void *b, const void *vf_ UNUSED)
{
- return -compare_value_numeric_a (a, b, aux);
+ return -compare_value_numeric_a (a, b, vf_);
}
/* Descending string compare of values. */
static int
-compare_value_alpha_d (const void *a, const void *b, const void *v)
+compare_value_alpha_d (const void *a, const void *b, const void *vf_)
{
- return -compare_value_alpha_a (a, b, v);
+ return -compare_value_alpha_a (a, b, vf_);
}
/* Ascending numeric compare of frequency;
secondary key on ascending numeric value. */
static int
-compare_freq_numeric_a (const void *a_, const void *b_, const void *aux UNUSED)
+compare_freq_numeric_a (const void *a_, const void *b_, const void *vf_ UNUSED)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
+ const struct freq *a = a_;
+ const struct freq *b = b_;
if (a->count > b->count)
return 1;
/* Ascending numeric compare of frequency;
secondary key on ascending string value. */
static int
-compare_freq_alpha_a (const void *a_, const void *b_, const void *v_)
+compare_freq_alpha_a (const void *a_, const void *b_, const void *vf_)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
- const struct variable *v = v_;
- struct var_freqs *vf = get_var_freqs (v);
+ const struct freq *a = a_;
+ const struct freq *b = b_;
+ const struct var_freqs *vf = vf_;
if (a->count > b->count)
return 1;
/* Descending numeric compare of frequency;
secondary key on ascending numeric value. */
static int
-compare_freq_numeric_d (const void *a_, const void *b_, const void *aux UNUSED)
+compare_freq_numeric_d (const void *a_, const void *b_, const void *vf_ UNUSED)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
+ const struct freq *a = a_;
+ const struct freq *b = b_;
if (a->count > b->count)
return -1;
/* Descending numeric compare of frequency;
secondary key on ascending string value. */
static int
-compare_freq_alpha_d (const void *a_, const void *b_, const void *v_)
+compare_freq_alpha_d (const void *a_, const void *b_, const void *vf_)
{
- const struct freq_mutable *a = a_;
- const struct freq_mutable *b = b_;
- const struct variable *v = v_;
- struct var_freqs *vf = get_var_freqs (v);
+ const struct freq *a = a_;
+ const struct freq *b = b_;
+ const struct var_freqs *vf = vf_;
if (a->count > b->count)
return -1;
/* Displays a full frequency table for variable V. */
static void
-dump_freq_table (const struct variable *v, const struct variable *wv)
+dump_freq_table (const struct var_freqs *vf, const struct variable *wv)
{
const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : &F_8_0;
+ const struct freq_tab *ft = &vf->tab;
int n_categories;
- struct var_freqs *vf;
- struct freq_tab *ft;
- struct freq_mutable *f;
+ struct freq *f;
struct tab_table *t;
int r, x;
double cum_total = 0.0;
N_("Cum Percent")
};
- vf = get_var_freqs (v);
- ft = &vf->tab;
n_categories = ft->n_valid + ft->n_missing;
t = tab_create (6, n_categories + 2);
tab_headers (t, 0, 0, 1, 0);
valid_percent = f->count / ft->valid_cases * 100.0;
cum_total += valid_percent;
- label = var_lookup_value_label (v, &f->value);
+ label = var_lookup_value_label (vf->var, &f->value);
if (label != NULL)
tab_text (t, 0, r, TAB_LEFT, label);
cum_freq += f->count;
- label = var_lookup_value_label (v, &f->value);
+ label = var_lookup_value_label (vf->var, &f->value);
if (label != NULL)
tab_text (t, 0, r, TAB_LEFT, label);
tab_fixed (t, 3, r, TAB_NONE, 100.0, 5, 1);
tab_fixed (t, 4, r, TAB_NONE, 100.0, 5, 1);
- tab_title (t, "%s", var_to_string (v));
+ tab_title (t, "%s", var_to_string (vf->var));
tab_submit (t);
}
\f
/* Calculates all the pertinent statistics for variable V, putting them in
array D[]. */
static void
-calc_stats (const struct variable *v, double d[frq_n_stats])
+calc_stats (const struct var_freqs *vf, double d[FRQ_N_STATS])
{
- struct freq_tab *ft = &get_var_freqs (v)->tab;
+ const struct freq_tab *ft = &vf->tab;
double W = ft->valid_cases;
struct moments *m;
- struct freq_mutable *f=0;
+ struct freq *f=0;
int most_often;
double X_mode;
for (i = 0; i < n_percentiles; i++)
{
- struct freq_tab *ft = &get_var_freqs (v)->tab;
double s;
double dummy;
moments_pass_one (m, f->value.f, f->count);
for (f = ft->valid; f < ft->missing; f++)
moments_pass_two (m, f->value.f, f->count);
- moments_calculate (m, NULL, &d[frq_mean], &d[frq_variance],
- &d[frq_skew], &d[frq_kurt]);
+ moments_calculate (m, NULL, &d[FRQ_MEAN], &d[FRQ_VARIANCE],
+ &d[FRQ_SKEW], &d[FRQ_KURT]);
moments_destroy (m);
/* Formulas below are taken from _SPSS Statistical Algorithms_. */
- d[frq_min] = ft->valid[0].value.f;
- d[frq_max] = ft->valid[ft->n_valid - 1].value.f;
- d[frq_mode] = X_mode;
- d[frq_range] = d[frq_max] - d[frq_min];
- d[frq_sum] = d[frq_mean] * W;
- d[frq_stddev] = sqrt (d[frq_variance]);
- d[frq_semean] = d[frq_stddev] / sqrt (W);
- d[frq_seskew] = calc_seskew (W);
- d[frq_sekurt] = calc_sekurt (W);
+ d[FRQ_MIN] = ft->valid[0].value.f;
+ d[FRQ_MAX] = ft->valid[ft->n_valid - 1].value.f;
+ d[FRQ_MODE] = X_mode;
+ d[FRQ_RANGE] = d[FRQ_MAX] - d[FRQ_MIN];
+ d[FRQ_SUM] = d[FRQ_MEAN] * W;
+ d[FRQ_STDDEV] = sqrt (d[FRQ_VARIANCE]);
+ d[FRQ_SEMEAN] = d[FRQ_STDDEV] / sqrt (W);
+ d[FRQ_SESKEW] = calc_seskew (W);
+ d[FRQ_SEKURT] = calc_sekurt (W);
}
/* Displays a table of all the statistics requested for variable V. */
static void
-dump_statistics (const struct variable *v, const struct variable *wv)
+dump_statistics (const struct var_freqs *vf, const struct variable *wv)
{
const struct fmt_spec *wfmt = wv ? var_get_print_format (wv) : &F_8_0;
- struct freq_tab *ft;
- double stat_value[frq_n_stats];
+ const struct freq_tab *ft = &vf->tab;
+ double stat_value[FRQ_N_STATS];
struct tab_table *t;
int i, r;
- if (var_is_alpha (v))
+ if (var_is_alpha (vf->var))
return;
- ft = &get_var_freqs (v)->tab;
+
if (ft->n_valid == 0)
{
msg (SW, _("No valid data for variable %s; statistics not displayed."),
- var_get_name (v));
+ var_get_name (vf->var));
return;
}
- calc_stats (v, stat_value);
+ calc_stats (vf, stat_value);
t = tab_create (3, n_stats + n_show_percentiles + 2);
r=2; /* N missing and N valid are always dumped */
- for (i = 0; i < frq_n_stats; i++)
+ for (i = 0; i < FRQ_N_STATS; i++)
if (stats & BIT_INDEX (i))
{
tab_text (t, 0, r, TAB_LEFT | TAT_TITLE,
else
tab_fixed (t, 1, r, TAB_LEFT, percentiles[i].p * 100, 3, 0);
tab_double (t, 2, r, TAB_NONE, percentiles[i].value,
- var_get_print_format (v));
+ var_get_print_format (vf->var));
}
- tab_title (t, "%s", var_to_string (v));
+ tab_title (t, "%s", var_to_string (vf->var));
tab_submit (t);
}
valid_freq = 0;
for (i = 0; i < ft->n_valid; i++)
{
- const struct freq_mutable *frq = &ft->valid[i];
+ const struct freq *frq = &ft->valid[i];
if (chart_includes_value (&hist, var, &frq->value))
{
x_min = MIN (x_min, frq->value.f);
histogram = histogram_create (bins, x_min, x_max);
for (i = 0; i < ft->n_valid; i++)
{
- const struct freq_mutable *frq = &ft->valid[i];
+ const struct freq *frq = &ft->valid[i];
if (chart_includes_value (&hist, var, &frq->value))
histogram_add (histogram, frq->value.f, frq->count);
}
}
static int
-add_slice (const struct freq_mutable *freq, const struct variable *var,
+add_slice (const struct freq *freq, const struct variable *var,
struct slice *slice)
{
if (chart_includes_value (&pie, var, &freq->value))