From bceed76f85dffbe6e4c054108c1dc1b6ee51b8d1 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 29 Jan 2022 16:57:26 -0800 Subject: [PATCH] ctables: Support mode (untested). --- src/language/stats/ctables.c | 37 +++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index 5f9d2584c8..17032c8c8e 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -35,6 +35,7 @@ #include "libpspp/hmap.h" #include "libpspp/message.h" #include "libpspp/string-array.h" +#include "math/mode.h" #include "math/moments.h" #include "math/percentiles.h" #include "math/sort.h" @@ -1685,11 +1686,12 @@ union ctables_summary /* MEAN, SEMEAN, STDDEV, SUM, VARIANCE, *.SUM. */ struct moments1 *moments; + /* MEDIAN, MODE. */ struct { struct casewriter *writer; - double mvalid; - double median; + double ovalid; + double ovalue; }; /* XXX percentiles, mode, multiple response */ @@ -1754,6 +1756,7 @@ ctables_summary_init (union ctables_summary *s, break; case CTSF_MEDIAN: + case CTSF_MODE: { struct caseproto *proto = caseproto_create (); proto = caseproto_add_width (proto, 0); @@ -1765,12 +1768,11 @@ ctables_summary_init (union ctables_summary *s, subcase_uninit (&ordering); caseproto_unref (proto); - s->mvalid = 0; - s->median = SYSMIS; + s->ovalid = 0; + s->ovalue = SYSMIS; } break; - case CTSF_MODE: case CTSF_PTILE: NOT_REACHED (); @@ -1857,10 +1859,10 @@ ctables_summary_uninit (union ctables_summary *s, break; case CTSF_MEDIAN: + case CTSF_MODE: casewriter_destroy (s->writer); break; - case CTSF_MODE: case CTSF_PTILE: NOT_REACHED (); @@ -1962,9 +1964,10 @@ ctables_summary_add (union ctables_summary *s, break; case CTSF_MEDIAN: + case CTSF_MODE: if (var_is_value_missing (var, value)) { - s->mvalid += weight; + s->ovalid += weight; struct ccase *c = case_create (casewriter_get_proto (s->writer)); *case_num_rw_idx (c, 0) = value->f; @@ -1973,7 +1976,6 @@ ctables_summary_add (union ctables_summary *s, } break; - case CTSF_MODE: case CTSF_PTILE: NOT_REACHED (); @@ -2121,15 +2123,28 @@ ctables_summary_value (const struct ctables_cell *cell, struct casereader *reader = casewriter_make_reader (s->writer); s->writer = NULL; - struct percentile *median = percentile_create (0.5, s->mvalid); + struct percentile *median = percentile_create (0.5, s->ovalid); struct order_stats *os = &median->parent; order_stats_accumulate_idx (&os, 1, reader, 1, 0); - s->median = percentile_calculate (median, PC_HAVERAGE); + s->ovalue = percentile_calculate (median, PC_HAVERAGE); statistic_destroy (&median->parent.parent); } - return s->median; + return s->ovalue; case CTSF_MODE: + if (s->writer) + { + struct casereader *reader = casewriter_make_reader (s->writer); + s->writer = NULL; + + struct mode *mode = mode_create (); + struct order_stats *os = &mode->parent; + order_stats_accumulate_idx (&os, 1, reader, 1, 0); + s->ovalue = mode->mode; + statistic_destroy (&mode->parent.parent); + } + return s->ovalue; + case CTSF_PTILE: NOT_REACHED (); -- 2.30.2