X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fctables.c;h=20f18916c85ba619976d227d222eaa27179b3676;hb=033449d465fb54526d3984d55772e6a38e7d922c;hp=fd296a00216e5165bcbe9427fc79cd99ccf71128;hpb=69b31e124aff05df3492e6e6412c03c64e4e9d12;p=pspp diff --git a/src/language/stats/ctables.c b/src/language/stats/ctables.c index fd296a0021..20f18916c8 100644 --- a/src/language/stats/ctables.c +++ b/src/language/stats/ctables.c @@ -63,47 +63,106 @@ enum ctables_vlabel CTVL_BOTH = SETTINGS_VALUE_SHOW_BOTH, }; -/* XXX: - - unweighted summaries (U*) - - lower confidence limits (*.LCL) - - upper confidence limits (*.UCL) - - standard error (*.SE) - */ +enum ctables_function_type + { + /* A function that operates on data in a single cell. The function does + not have an unweighted version. */ + CTFT_CELL, + + /* A function that operates on data in a single cell. The function has an + unweighted version. */ + CTFT_UCELL, + + /* A function that operates on an area of cells. The function has an + unweighted version. */ + CTFT_AREA, + }; + +enum ctables_format + { + CTF_COUNT, + CTF_PERCENT, + CTF_GENERAL + }; + +enum ctables_function_availability + { + CTFA_ALL, /* Any variables. */ + CTFA_SCALE, /* Only scale variables, totals, and subtotals. */ + //CTFA_MRSETS, /* Only multiple-response sets */ + }; enum ctables_summary_function { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) ENUM, +#define S(ENUM, NAME, TYPE, FORMAT, AVAILABILITY) ENUM, #include "ctables.inc" #undef S }; enum { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) +1 +#define S(ENUM, NAME, TYPE, FORMAT, AVAILABILITY) +1 N_CTSF_FUNCTIONS = #include "ctables.inc" #undef S }; +struct ctables_function_info + { + struct substring basename; + enum ctables_function_type type; + enum ctables_format format; + enum ctables_function_availability availability; + + bool may_be_unweighted; + bool is_area; + }; +static const struct ctables_function_info ctables_function_info[N_CTSF_FUNCTIONS] = { +#define S(ENUM, NAME, TYPE, FORMAT, AVAILABILITY) \ + [ENUM] = { \ + .basename = SS_LITERAL_INITIALIZER (NAME), \ + .type = TYPE, \ + .format = FORMAT, \ + .availability = AVAILABILITY, \ + .may_be_unweighted = (TYPE) == CTFT_UCELL || (TYPE) == CTFT_AREA, \ + .is_area = (TYPE) == CTFT_AREA \ + }, +#include "ctables.inc" +#undef S +}; + static bool ctables_summary_function_is_count (enum ctables_summary_function); -enum ctables_domain_type +enum ctables_area_type { /* Within a section, where stacked variables divide one section from - another. */ - CTDT_TABLE, /* All layers of a whole section. */ - CTDT_LAYER, /* One layer within a section. */ - CTDT_LAYERROW, /* Row in one layer within a section. */ - CTDT_LAYERCOL, /* Column in one layer within a section. */ + another. + + Keep CTAT_LAYER after CTAT_LAYERROW and CTAT_LAYERCOL so that + parse_ctables_summary_function() parses correctly. */ + CTAT_TABLE, /* All layers of a whole section. */ + CTAT_LAYERROW, /* Row in one layer within a section. */ + CTAT_LAYERCOL, /* Column in one layer within a section. */ + CTAT_LAYER, /* One layer within a section. */ /* Within a subtable, where a subtable pairs an innermost row variable with an innermost column variable within a single layer. */ - CTDT_SUBTABLE, /* Whole subtable. */ - CTDT_ROW, /* Row within a subtable. */ - CTDT_COL, /* Column within a subtable. */ -#define N_CTDTS 7 + CTAT_SUBTABLE, /* Whole subtable. */ + CTAT_ROW, /* Row within a subtable. */ + CTAT_COL, /* Column within a subtable. */ +#define N_CTATS 7 }; -struct ctables_domain +static const char *ctables_area_type_name[N_CTATS] = { + [CTAT_TABLE] = "TABLE", + [CTAT_LAYER] = "LAYER", + [CTAT_LAYERROW] = "LAYERROW", + [CTAT_LAYERCOL] = "LAYERCOL", + [CTAT_SUBTABLE] = "SUBTABLE", + [CTAT_ROW] = "ROW", + [CTAT_COL] = "COL", +}; + +struct ctables_area { struct hmap_node node; @@ -141,9 +200,9 @@ struct ctables_cell all the axes (except the scalar variable, if any). */ struct hmap_node node; - /* The domains that contain this cell. */ - uint32_t omit_domains; - struct ctables_domain *domains[N_CTDTS]; + /* The areas that contain this cell. */ + uint32_t omit_areas; + struct ctables_area *areas[N_CTATS]; bool hide; @@ -314,8 +373,8 @@ struct ctables_nest struct variable **vars; size_t n; size_t scale_idx; - size_t *domains[N_CTDTS]; - size_t n_domains[N_CTDTS]; + size_t *areas[N_CTATS]; + size_t n_areas[N_CTATS]; size_t group_head; struct ctables_summary_spec_set specs[N_CSVS]; @@ -352,7 +411,7 @@ struct ctables_section /* Data. */ struct hmap *occurrences[PIVOT_N_AXES]; /* "struct ctables_occurrence"s. */ struct hmap cells; /* Contains "struct ctables_cell"s. */ - struct hmap domains[N_CTDTS]; /* Contains "struct ctables_domain"s. */ + struct hmap areas[N_CTATS]; /* Contains "struct ctables_area"s. */ }; static void ctables_section_uninit (struct ctables_section *); @@ -482,6 +541,8 @@ struct ctables_category /* CCT_FUNCTION. */ enum ctables_summary_function sort_function; + bool weighted; + enum ctables_area_type area; struct variable *sort_var; double percentile; }; @@ -672,26 +733,34 @@ struct ctables_axis static void ctables_axis_destroy (struct ctables_axis *); -enum ctables_format - { - CTF_COUNT, - CTF_PERCENT, - CTF_GENERAL - }; - -enum ctables_function_availability - { - CTFA_ALL, /* Any variables. */ - CTFA_SCALE, /* Only scale variables, totals, and subtotals. */ - //CTFA_MRSETS, /* Only multiple-response sets */ - }; - struct ctables_summary_spec { + /* The calculation to be performed. + + 'function' is the function to calculate. 'weighted' specifies whether + to use weighted or unweighted data (for functions that do not support a + choice, it must be true). 'calc_area' is the area over which the + calculation takes place (for functions that target only an individual + cell, it must be 0). For CTSF_PTILE only, 'percentile' is the + percentile between 0 and 100 (for other functions it must be 0). */ enum ctables_summary_function function; + bool weighted; + enum ctables_area_type calc_area; double percentile; /* CTSF_PTILE only. */ - char *label; + /* How to display the result of the calculation. + + 'label' is a user-specified label, NULL if the user didn't specify + one. + + 'user_area' is usually the same as 'calc_area', but when category labels + are rotated from one axis to another it swaps rows and columns. + + 'format' is the format for displaying the output. If + 'is_ctables_format' is true, then 'format.type' is one of the special + CTEF_* formats instead of the standard ones. */ + char *label; + enum ctables_area_type user_area; struct fmt_spec format; bool is_ctables_format; /* Is 'format' one of CTEF_*? */ @@ -777,7 +846,7 @@ static enum ctables_function_availability ctables_function_availability (enum ctables_summary_function f) { static enum ctables_function_availability availability[] = { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) [ENUM] = AVAILABILITY, +#define S(ENUM, NAME, TYPE, FORMAT, AVAILABILITY) [ENUM] = AVAILABILITY, #include "ctables.inc" #undef S }; @@ -788,44 +857,55 @@ ctables_function_availability (enum ctables_summary_function f) static bool ctables_summary_function_is_count (enum ctables_summary_function f) { - return f == CTSF_COUNT || f == CTSF_ECOUNT || f == CTSF_UCOUNT; + return f == CTSF_COUNT || f == CTSF_ECOUNT; } static bool parse_ctables_summary_function (struct lexer *lexer, - enum ctables_summary_function *f) + enum ctables_summary_function *function, + bool *weighted, + enum ctables_area_type *area) { - struct pair - { - enum ctables_summary_function function; - struct substring name; - }; - static struct pair names[] = { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) \ - { ENUM, SS_LITERAL_INITIALIZER (NAME) }, -#include "ctables.inc" - /* The .COUNT suffix may be omitted. */ - S(CTSF_ROWPCT_COUNT, "ROWPCT", _, _, _) - S(CTSF_COLPCT_COUNT, "COLPCT", _, _, _) - S(CTSF_TABLEPCT_COUNT, "TABLEPCT", _, _, _) - S(CTSF_SUBTABLEPCT_COUNT, "SUBTABLEPCT", _, _, _) - S(CTSF_LAYERPCT_COUNT, "LAYERPCT", _, _, _) - S(CTSF_LAYERROWPCT_COUNT, "LAYERROWPCT", _, _, _) - S(CTSF_LAYERCOLPCT_COUNT, "LAYERCOLPCT", _, _, _) -#undef S - }; - if (!lex_force_id (lexer)) return false; - for (size_t i = 0; i < sizeof names / sizeof *names; i++) - if (ss_equals_case (names[i].name, lex_tokss (lexer))) + struct substring name = lex_tokss (lexer); + *weighted = !(ss_match_byte (&name, 'U') || ss_match_byte (&name, 'u')); + + bool has_area = false; + *area = 0; + for (enum ctables_area_type at = 0; at < N_CTATS; at++) + if (ss_match_string_case (&name, ss_cstr (ctables_area_type_name[at]))) { - *f = names[i].function; - lex_get (lexer); - return true; + has_area = true; + *area = at; + + if (ss_equals_case (name, ss_cstr ("PCT"))) + { + /* Special case where .COUNT suffix is omitted. */ + *function = CTSF_areaPCT_COUNT; + lex_get (lexer); + return true; + } + break; } + for (int f = 0; f < N_CTSF_FUNCTIONS; f++) + { + const struct ctables_function_info *cfi = &ctables_function_info[f]; + if (ss_equals_case (cfi->basename, name)) + { + *function = f; + if (!*weighted && !cfi->may_be_unweighted) + break; + if (has_area != cfi->is_area) + break; + + lex_get (lexer); + return true; + } + } + lex_error (lexer, _("Expecting summary function name.")); return false; } @@ -881,7 +961,7 @@ ctables_summary_default_format (enum ctables_summary_function function, const struct variable *var) { static const enum ctables_format default_formats[] = { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) [ENUM] = FORMAT, +#define S(ENUM, NAME, TYPE, FORMAT, AVAILABILITY) [ENUM] = FORMAT, #include "ctables.inc" #undef S }; @@ -901,21 +981,120 @@ ctables_summary_default_format (enum ctables_summary_function function, } } +static const char * +ctables_summary_label__ (const struct ctables_summary_spec *spec) +{ + bool w = spec->weighted; + enum ctables_area_type a = spec->user_area; + switch (spec->function) + { + case CTSF_COUNT: + return w ? N_("Count") : N_("Unweighted Count"); + + case CTSF_ECOUNT: + return N_("Adjusted Count"); + + case CTSF_areaPCT_COUNT: + switch (a) + { + case CTAT_TABLE: return w ? N_("Table %") : N_("Unweighted Table %"); + case CTAT_LAYER: return w ? N_("Layer %") : N_("Unweighted Layer %"); + case CTAT_LAYERROW: return w ? N_("Layer Row %") : N_("Unweighted Layer Row %"); + case CTAT_LAYERCOL: return w ? N_("Layer Column %") : N_("Unweighted Layer Column %"); + case CTAT_SUBTABLE: return w ? N_("Subtable %") : N_("Unweighted Subtable %"); + case CTAT_ROW: return w ? N_("Row %") : N_("Unweighted Row %"); + case CTAT_COL: return w ? N_("Column %") : N_("Unweighted Column %"); + } + NOT_REACHED (); + + case CTSF_areaPCT_VALIDN: + switch (a) + { + case CTAT_TABLE: return w ? N_("Table Valid N %") : N_("Unweighted Table Valid N %"); + case CTAT_LAYER: return w ? N_("Layer Valid N %") : N_("Unweighted Layer Valid N %"); + case CTAT_LAYERROW: return w ? N_("Layer Row Valid N %") : N_("Unweighted Layer Row Valid N %"); + case CTAT_LAYERCOL: return w ? N_("Layer Column Valid N %") : N_("Unweighted Layer Column Valid N %"); + case CTAT_SUBTABLE: return w ? N_("Subtable Valid N %") : N_("Unweighted Subtable Valid N %"); + case CTAT_ROW: return w ? N_("Row Valid N %") : N_("Unweighted Row Valid N %"); + case CTAT_COL: return w ? N_("Column Valid N %") : N_("Unweighted Column Valid N %"); + } + NOT_REACHED (); + + case CTSF_areaPCT_TOTALN: + switch (a) + { + case CTAT_TABLE: return w ? N_("Table Total N %") : N_("Unweighted Table Total N %"); + case CTAT_LAYER: return w ? N_("Layer Total N %") : N_("Unweighted Layer Total N %"); + case CTAT_LAYERROW: return w ? N_("Layer Row Total N %") : N_("Unweighted Layer Row Total N %"); + case CTAT_LAYERCOL: return w ? N_("Layer Column Total N %") : N_("Unweighted Layer Column Total N %"); + case CTAT_SUBTABLE: return w ? N_("Subtable Total N %") : N_("Unweighted Subtable Total N %"); + case CTAT_ROW: return w ? N_("Row Total N %") : N_("Unweighted Row Total N %"); + case CTAT_COL: return w ? N_("Column Total N %") : N_("Unweighted Column Total N %"); + } + NOT_REACHED (); + + case CTSF_MAXIMUM: return N_("Maximum"); + case CTSF_MEAN: return w ? N_("Mean") : N_("Unweighted Mean"); + case CTSF_MEDIAN: return N_("Median"); + case CTSF_MINIMUM: return N_("Minimum"); + case CTSF_MISSING: return N_("Missing"); + case CTSF_MODE: return N_("Mode"); + case CTSF_PTILE: NOT_REACHED (); + case CTSF_RANGE: return N_("Range"); + case CTSF_SEMEAN: return N_("Std Error of Mean"); + case CTSF_STDDEV: return N_("Std Deviation"); + case CTSF_SUM: return N_("Sum"); + case CTSF_TOTALN: return N_("Total N"); + case CTSF_ETOTALN: return N_("Adjusted Total N"); + case CTSF_VALIDN: return N_("Valid N"); + case CTSF_EVALIDN: return N_("Adjusted Valid N"); + case CTSF_VARIANCE: return N_("Variance"); + case CTSF_areaPCT_SUM: + switch (a) + { + case CTAT_TABLE: return w ? N_("Table Sum %") : N_("Unweighted Table Sum %"); + case CTAT_LAYER: return w ? N_("Layer Sum %") : N_("Unweighted Layer Sum %"); + case CTAT_LAYERROW: return w ? N_("Layer Row Sum %") : N_("Unweighted Layer Row Sum %"); + case CTAT_LAYERCOL: return w ? N_("Layer Column Sum %") : N_("Unweighted Layer Column Sum %"); + case CTAT_SUBTABLE: return w ? N_("Subtable Sum %") : N_("Unweighted Subtable Sum %"); + case CTAT_ROW: return w ? N_("Row Sum %") : N_("Unweighted Row Sum %"); + case CTAT_COL: return w ? N_("Column Sum %") : N_("Unweighted Column Sum %"); + } + NOT_REACHED (); + + case CTSF_areaID: + switch (a) + { + /* Don't bother translating these: they are for developers only. */ + case CTAT_TABLE: return "Table ID"; + case CTAT_LAYER: return "Layer ID"; + case CTAT_LAYERROW: return "Layer Row ID"; + case CTAT_LAYERCOL: return "Layer Column ID"; + case CTAT_SUBTABLE: return "Subtable ID"; + case CTAT_ROW: return "Row ID"; + case CTAT_COL: return "Column ID"; + } + NOT_REACHED (); + } + + NOT_REACHED (); +} + static struct pivot_value * ctables_summary_label (const struct ctables_summary_spec *spec, double cilevel) { if (!spec->label) { - static const char *default_labels[] = { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) [ENUM] = LABEL, -#include "ctables.inc" -#undef S - }; - - return (spec->function == CTSF_PTILE - ? pivot_value_new_text_format (N_("Percentile %.2f"), - spec->percentile) - : pivot_value_new_text (default_labels[spec->function])); + if (spec->function == CTSF_PTILE) + { + double p = spec->percentile; + char *s = (spec->weighted + ? xasprintf (_("Percentile %.2f"), p) + : xasprintf (_("Unweighted Percentile %.2f"), p)); + return pivot_value_new_user_text_nocopy (s); + } + else + return pivot_value_new_text (ctables_summary_label__ (spec)); } else { @@ -930,7 +1109,7 @@ ctables_summary_label (const struct ctables_summary_spec *spec, double cilevel) ss_advance (&in, chunk); if (!in.length) return pivot_value_new_user_text_nocopy (ds_steal_cstr (&out)); - + ss_advance (&in, target.length); ds_put_format (&out, "%g", cilevel); } @@ -938,26 +1117,32 @@ ctables_summary_label (const struct ctables_summary_spec *spec, double cilevel) } static const char * -ctables_summary_function_name (enum ctables_summary_function function) +ctables_summary_function_name (enum ctables_summary_function function, + bool weighted, + enum ctables_area_type area, + char *buffer, size_t bufsize) { - static const char *names[] = { -#define S(ENUM, NAME, LABEL, FORMAT, AVAILABILITY) [ENUM] = NAME, -#include "ctables.inc" -#undef S - }; - return names[function]; + const struct ctables_function_info *cfi = &ctables_function_info[function]; + snprintf (buffer, bufsize, "%s%s%s", + weighted ? "" : "U", + cfi->is_area ? ctables_area_type_name[area] : "", + cfi->basename.string); + return buffer; } static bool add_summary_spec (struct ctables_axis *axis, - enum ctables_summary_function function, double percentile, + enum ctables_summary_function function, bool weighted, + enum ctables_area_type area, double percentile, const char *label, const struct fmt_spec *format, bool is_ctables_format, const struct msg_location *loc, enum ctables_summary_variant sv) { if (axis->op == CTAO_VAR) { - const char *function_name = ctables_summary_function_name (function); + char function_name[128]; + ctables_summary_function_name (function, weighted, area, + function_name, sizeof function_name); const char *var_name = var_get_name (axis->var); switch (ctables_function_availability (function)) { @@ -994,6 +1179,9 @@ add_summary_spec (struct ctables_axis *axis, struct ctables_summary_spec *dst = &set->specs[set->n++]; *dst = (struct ctables_summary_spec) { .function = function, + .weighted = weighted, + .calc_area = area, + .user_area = area, .percentile = percentile, .label = xstrdup_if_nonnull (label), .format = (format ? *format @@ -1005,8 +1193,9 @@ add_summary_spec (struct ctables_axis *axis, else { for (size_t i = 0; i < 2; i++) - if (!add_summary_spec (axis->subs[i], function, percentile, label, - format, is_ctables_format, loc, sv)) + if (!add_summary_spec (axis->subs[i], function, weighted, area, + percentile, label, format, is_ctables_format, + loc, sv)) return false; return true; } @@ -1122,7 +1311,10 @@ ctables_axis_parse_postfix (struct ctables_axis_parse_ctx *ctx) /* Parse function. */ enum ctables_summary_function function; - if (!parse_ctables_summary_function (ctx->lexer, &function)) + bool weighted; + enum ctables_area_type area; + if (!parse_ctables_summary_function (ctx->lexer, &function, &weighted, + &area)) goto error; /* Parse percentile. */ @@ -1163,8 +1355,8 @@ ctables_axis_parse_postfix (struct ctables_axis_parse_ctx *ctx) struct msg_location *loc = lex_ofs_location (ctx->lexer, start_ofs, lex_ofs (ctx->lexer) - 1); - add_summary_spec (sub, function, percentile, label, formatp, - is_ctables_format, loc, sv); + add_summary_spec (sub, function, weighted, area, percentile, label, + formatp, is_ctables_format, loc, sv); free (label); msg_location_destroy (loc); @@ -1912,7 +2104,8 @@ ctables_table_parse_categories (struct lexer *lexer, struct dictionary *dict, else { cat.type = CCT_FUNCTION; - if (!parse_ctables_summary_function (lexer, &cat.sort_function)) + if (!parse_ctables_summary_function (lexer, &cat.sort_function, + &cat.weighted, &cat.area)) goto error; if (lex_match (lexer, T_LPAREN)) @@ -2174,8 +2367,8 @@ ctables_nest_uninit (struct ctables_nest *nest) free (nest->vars); for (enum ctables_summary_variant sv = 0; sv < N_CSVS; sv++) ctables_summary_spec_set_uninit (&nest->specs[sv]); - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) - free (nest->domains[dt]); + for (enum ctables_area_type at = 0; at < N_CTATS; at++) + free (nest->areas[at]); } static void @@ -2336,67 +2529,18 @@ ctables_summary_init (union ctables_summary *s, { case CTSF_COUNT: case CTSF_ECOUNT: - case CTSF_ROWPCT_COUNT: - case CTSF_COLPCT_COUNT: - case CTSF_TABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERCOLPCT_COUNT: - case CTSF_ROWPCT_VALIDN: - case CTSF_COLPCT_VALIDN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_LAYERCOLPCT_VALIDN: - case CTSF_ROWPCT_TOTALN: - case CTSF_COLPCT_TOTALN: - case CTSF_TABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERCOLPCT_TOTALN: + case CTSF_areaPCT_COUNT: + case CTSF_areaPCT_VALIDN: + case CTSF_areaPCT_TOTALN: case CTSF_MISSING: - case CSTF_TOTALN: + case CTSF_TOTALN: case CTSF_ETOTALN: case CTSF_VALIDN: case CTSF_EVALIDN: - case CTSF_UCOUNT: - case CTSF_UROWPCT_COUNT: - case CTSF_UCOLPCT_COUNT: - case CTSF_UTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERCOLPCT_COUNT: - case CTSF_UROWPCT_VALIDN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_ULAYERCOLPCT_VALIDN: - case CTSF_UROWPCT_TOTALN: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERCOLPCT_TOTALN: - case CTSF_UMISSING: - case CSTF_UTOTALN: - case CTSF_UVALIDN: s->count = 0; break; - case CTSF_ROW_ID: - case CTSF_COL_ID: - case CTSF_TABLE_ID: - case CTSF_SUBTABLE_ID: - case CTSF_LAYER_ID: - case CTSF_LAYERROW_ID: - case CTSF_LAYERCOL_ID: + case CTSF_areaID: break; case CTSF_MAXIMUM: @@ -2410,34 +2554,13 @@ ctables_summary_init (union ctables_summary *s, case CTSF_STDDEV: case CTSF_SUM: case CTSF_VARIANCE: - case CTSF_ROWPCT_SUM: - case CTSF_COLPCT_SUM: - case CTSF_TABLEPCT_SUM: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_LAYERPCT_SUM: - case CTSF_LAYERROWPCT_SUM: - case CTSF_LAYERCOLPCT_SUM: - case CTSF_UMEAN: - case CTSF_USEMEAN: - case CTSF_USTDDEV: - case CTSF_USUM: - case CTSF_UVARIANCE: - case CTSF_UROWPCT_SUM: - case CTSF_UCOLPCT_SUM: - case CTSF_UTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_ULAYERPCT_SUM: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ULAYERCOLPCT_SUM: + case CTSF_areaPCT_SUM: s->moments = moments1_create (MOMENT_VARIANCE); break; case CTSF_MEDIAN: case CTSF_MODE: case CTSF_PTILE: - case CTSF_UMEDIAN: - case CTSF_UMODE: - case CTSF_UPTILE: { struct caseproto *proto = caseproto_create (); proto = caseproto_add_width (proto, 0); @@ -2464,66 +2587,17 @@ ctables_summary_uninit (union ctables_summary *s, { case CTSF_COUNT: case CTSF_ECOUNT: - case CTSF_ROWPCT_COUNT: - case CTSF_COLPCT_COUNT: - case CTSF_TABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERCOLPCT_COUNT: - case CTSF_ROWPCT_VALIDN: - case CTSF_COLPCT_VALIDN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_LAYERCOLPCT_VALIDN: - case CTSF_ROWPCT_TOTALN: - case CTSF_COLPCT_TOTALN: - case CTSF_TABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERCOLPCT_TOTALN: + case CTSF_areaPCT_COUNT: + case CTSF_areaPCT_VALIDN: + case CTSF_areaPCT_TOTALN: case CTSF_MISSING: - case CSTF_TOTALN: + case CTSF_TOTALN: case CTSF_ETOTALN: case CTSF_VALIDN: case CTSF_EVALIDN: - case CTSF_UCOUNT: - case CTSF_UROWPCT_COUNT: - case CTSF_UCOLPCT_COUNT: - case CTSF_UTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERCOLPCT_COUNT: - case CTSF_UROWPCT_VALIDN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_ULAYERCOLPCT_VALIDN: - case CTSF_UROWPCT_TOTALN: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERCOLPCT_TOTALN: - case CTSF_UMISSING: - case CSTF_UTOTALN: - case CTSF_UVALIDN: break; - case CTSF_ROW_ID: - case CTSF_COL_ID: - case CTSF_TABLE_ID: - case CTSF_SUBTABLE_ID: - case CTSF_LAYER_ID: - case CTSF_LAYERROW_ID: - case CTSF_LAYERCOL_ID: + case CTSF_areaID: break; case CTSF_MAXIMUM: @@ -2536,34 +2610,13 @@ ctables_summary_uninit (union ctables_summary *s, case CTSF_STDDEV: case CTSF_SUM: case CTSF_VARIANCE: - case CTSF_ROWPCT_SUM: - case CTSF_COLPCT_SUM: - case CTSF_TABLEPCT_SUM: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_LAYERPCT_SUM: - case CTSF_LAYERROWPCT_SUM: - case CTSF_LAYERCOLPCT_SUM: - case CTSF_UMEAN: - case CTSF_USEMEAN: - case CTSF_USTDDEV: - case CTSF_USUM: - case CTSF_UVARIANCE: - case CTSF_UROWPCT_SUM: - case CTSF_UCOLPCT_SUM: - case CTSF_UTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_ULAYERPCT_SUM: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ULAYERCOLPCT_SUM: + case CTSF_areaPCT_SUM: moments1_destroy (s->moments); break; case CTSF_MEDIAN: case CTSF_MODE: case CTSF_PTILE: - case CTSF_UMEDIAN: - case CTSF_UMODE: - case CTSF_UPTILE: casewriter_destroy (s->writer); break; } @@ -2597,101 +2650,33 @@ ctables_summary_add (union ctables_summary *s, */ switch (ss->function) { - case CSTF_TOTALN: - case CTSF_ROWPCT_TOTALN: - case CTSF_COLPCT_TOTALN: - case CTSF_TABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERCOLPCT_TOTALN: - s->count += d_weight; - break; - - case CSTF_UTOTALN: - case CTSF_UROWPCT_TOTALN: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERCOLPCT_TOTALN: - s->count += 1.0; + case CTSF_TOTALN: + case CTSF_areaPCT_TOTALN: + s->count += ss->weighted ? d_weight : 1.0; break; case CTSF_COUNT: - case CTSF_ROWPCT_COUNT: - case CTSF_COLPCT_COUNT: - case CTSF_TABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERCOLPCT_COUNT: + case CTSF_areaPCT_COUNT: if (is_scale || !excluded_missing) - s->count += d_weight; - break; - - case CTSF_UCOUNT: - case CTSF_UROWPCT_COUNT: - case CTSF_UCOLPCT_COUNT: - case CTSF_UTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERCOLPCT_COUNT: - if (is_scale || !excluded_missing) - s->count += 1.0; + s->count += ss->weighted ? d_weight : 1.0; break; case CTSF_VALIDN: - case CTSF_ROWPCT_VALIDN: - case CTSF_COLPCT_VALIDN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_LAYERCOLPCT_VALIDN: + case CTSF_areaPCT_VALIDN: if (is_scale ? !is_scale_missing : !is_missing) - s->count += d_weight; + s->count += ss->weighted ? d_weight : 1.0; break; - case CTSF_UVALIDN: - case CTSF_UROWPCT_VALIDN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_ULAYERCOLPCT_VALIDN: - if (is_scale - ? !is_scale_missing - : !is_missing) - s->count += 1.0; - break; - - case CTSF_ROW_ID: - case CTSF_COL_ID: - case CTSF_TABLE_ID: - case CTSF_SUBTABLE_ID: - case CTSF_LAYER_ID: - case CTSF_LAYERROW_ID: - case CTSF_LAYERCOL_ID: + case CTSF_areaID: break; case CTSF_MISSING: if (is_scale ? is_scale_missing : is_missing) - s->count += d_weight; - break; - - case CTSF_UMISSING: - if (is_scale - ? is_scale_missing - : is_missing) - s->count += 1.0; + s->count += ss->weighted ? d_weight : 1.0; break; case CTSF_ECOUNT: @@ -2728,278 +2713,28 @@ ctables_summary_add (union ctables_summary *s, case CTSF_STDDEV: case CTSF_SUM: case CTSF_VARIANCE: - case CTSF_ROWPCT_SUM: - case CTSF_COLPCT_SUM: - case CTSF_TABLEPCT_SUM: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_LAYERPCT_SUM: - case CTSF_LAYERROWPCT_SUM: - case CTSF_LAYERCOLPCT_SUM: - if (!is_scale_missing) - moments1_add (s->moments, value->f, e_weight); - break; - - case CTSF_UMEAN: - case CTSF_USEMEAN: - case CTSF_USTDDEV: - case CTSF_USUM: - case CTSF_UVARIANCE: - case CTSF_UROWPCT_SUM: - case CTSF_UCOLPCT_SUM: - case CTSF_UTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_ULAYERPCT_SUM: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ULAYERCOLPCT_SUM: + case CTSF_areaPCT_SUM: if (!is_scale_missing) - moments1_add (s->moments, value->f, 1.0); + moments1_add (s->moments, value->f, ss->weighted ? e_weight : 1.0); break; - case CTSF_UMEDIAN: - case CTSF_UMODE: - case CTSF_UPTILE: - d_weight = e_weight = 1.0; - /* Fall through. */ case CTSF_MEDIAN: case CTSF_MODE: case CTSF_PTILE: if (!is_scale_missing) { - s->ovalid += e_weight; + double w = ss->weighted ? e_weight : 1.0; + s->ovalid += w; struct ccase *c = case_create (casewriter_get_proto (s->writer)); *case_num_rw_idx (c, 0) = value->f; - *case_num_rw_idx (c, 1) = e_weight; + *case_num_rw_idx (c, 1) = w; casewriter_write (s->writer, c); } break; } } -static enum ctables_domain_type -ctables_function_domain (enum ctables_summary_function function) -{ - switch (function) - { - case CTSF_COUNT: - case CTSF_ECOUNT: - case CTSF_MISSING: - case CSTF_TOTALN: - case CTSF_ETOTALN: - case CTSF_VALIDN: - case CTSF_EVALIDN: - case CTSF_MAXIMUM: - case CTSF_MINIMUM: - case CTSF_RANGE: - case CTSF_MEAN: - case CTSF_SEMEAN: - case CTSF_STDDEV: - case CTSF_SUM: - case CTSF_VARIANCE: - case CTSF_MEDIAN: - case CTSF_PTILE: - case CTSF_MODE: - case CTSF_UCOUNT: - case CTSF_UMISSING: - case CSTF_UTOTALN: - case CTSF_UVALIDN: - case CTSF_UMEAN: - case CTSF_USEMEAN: - case CTSF_USTDDEV: - case CTSF_USUM: - case CTSF_UVARIANCE: - case CTSF_UMEDIAN: - case CTSF_UPTILE: - case CTSF_UMODE: - NOT_REACHED (); - - case CTSF_COLPCT_COUNT: - case CTSF_COLPCT_SUM: - case CTSF_COLPCT_TOTALN: - case CTSF_COLPCT_VALIDN: - case CTSF_UCOLPCT_COUNT: - case CTSF_UCOLPCT_SUM: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_COL_ID: - return CTDT_COL; - - case CTSF_LAYERCOLPCT_COUNT: - case CTSF_LAYERCOLPCT_SUM: - case CTSF_LAYERCOLPCT_TOTALN: - case CTSF_LAYERCOLPCT_VALIDN: - case CTSF_ULAYERCOLPCT_COUNT: - case CTSF_ULAYERCOLPCT_SUM: - case CTSF_ULAYERCOLPCT_TOTALN: - case CTSF_ULAYERCOLPCT_VALIDN: - case CTSF_LAYERCOL_ID: - return CTDT_LAYERCOL; - - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERPCT_SUM: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERPCT_SUM: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_LAYER_ID: - return CTDT_LAYER; - - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERROWPCT_SUM: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_LAYERROW_ID: - return CTDT_LAYERROW; - - case CTSF_ROWPCT_COUNT: - case CTSF_ROWPCT_SUM: - case CTSF_ROWPCT_TOTALN: - case CTSF_ROWPCT_VALIDN: - case CTSF_UROWPCT_COUNT: - case CTSF_UROWPCT_SUM: - case CTSF_UROWPCT_TOTALN: - case CTSF_UROWPCT_VALIDN: - case CTSF_ROW_ID: - return CTDT_ROW; - - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_SUBTABLE_ID: - return CTDT_SUBTABLE; - - case CTSF_TABLEPCT_COUNT: - case CTSF_TABLEPCT_SUM: - case CTSF_TABLEPCT_TOTALN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_UTABLEPCT_COUNT: - case CTSF_UTABLEPCT_SUM: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_TABLE_ID: - return CTDT_TABLE; - } - - NOT_REACHED (); -} - -static enum ctables_domain_type -ctables_function_is_pctsum (enum ctables_summary_function function) -{ - switch (function) - { - case CTSF_COUNT: - case CTSF_ECOUNT: - case CTSF_MISSING: - case CSTF_TOTALN: - case CTSF_ETOTALN: - case CTSF_VALIDN: - case CTSF_EVALIDN: - case CTSF_MAXIMUM: - case CTSF_MINIMUM: - case CTSF_RANGE: - case CTSF_MEAN: - case CTSF_SEMEAN: - case CTSF_STDDEV: - case CTSF_SUM: - case CTSF_VARIANCE: - case CTSF_MEDIAN: - case CTSF_PTILE: - case CTSF_MODE: - case CTSF_UCOUNT: - case CTSF_UMISSING: - case CSTF_UTOTALN: - case CTSF_UVALIDN: - case CTSF_UMEAN: - case CTSF_USEMEAN: - case CTSF_USTDDEV: - case CTSF_USUM: - case CTSF_UVARIANCE: - case CTSF_UMEDIAN: - case CTSF_UPTILE: - case CTSF_UMODE: - case CTSF_COLPCT_COUNT: - case CTSF_COLPCT_TOTALN: - case CTSF_COLPCT_VALIDN: - case CTSF_UCOLPCT_COUNT: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_LAYERCOLPCT_COUNT: - case CTSF_LAYERCOLPCT_TOTALN: - case CTSF_LAYERCOLPCT_VALIDN: - case CTSF_ULAYERCOLPCT_COUNT: - case CTSF_ULAYERCOLPCT_TOTALN: - case CTSF_ULAYERCOLPCT_VALIDN: - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_ROWPCT_COUNT: - case CTSF_ROWPCT_TOTALN: - case CTSF_ROWPCT_VALIDN: - case CTSF_UROWPCT_COUNT: - case CTSF_UROWPCT_TOTALN: - case CTSF_UROWPCT_VALIDN: - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_TABLEPCT_COUNT: - case CTSF_TABLEPCT_TOTALN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_UTABLEPCT_COUNT: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_ROW_ID: - case CTSF_COL_ID: - case CTSF_TABLE_ID: - case CTSF_SUBTABLE_ID: - case CTSF_LAYER_ID: - case CTSF_LAYERROW_ID: - case CTSF_LAYERCOL_ID: - return false; - - case CTSF_COLPCT_SUM: - case CTSF_UCOLPCT_SUM: - case CTSF_LAYERCOLPCT_SUM: - case CTSF_ULAYERCOLPCT_SUM: - case CTSF_LAYERPCT_SUM: - case CTSF_ULAYERPCT_SUM: - case CTSF_LAYERROWPCT_SUM: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ROWPCT_SUM: - case CTSF_UROWPCT_SUM: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_TABLEPCT_SUM: - case CTSF_UTABLEPCT_SUM: - return true; - } - - NOT_REACHED (); -} - static double ctables_summary_value (const struct ctables_cell *cell, union ctables_summary *s, @@ -3009,109 +2744,36 @@ ctables_summary_value (const struct ctables_cell *cell, { case CTSF_COUNT: case CTSF_ECOUNT: - case CTSF_UCOUNT: return s->count; - case CTSF_ROW_ID: - case CTSF_COL_ID: - case CTSF_TABLE_ID: - case CTSF_SUBTABLE_ID: - case CTSF_LAYER_ID: - case CTSF_LAYERROW_ID: - case CTSF_LAYERCOL_ID: - return cell->domains[ctables_function_domain (ss->function)]->sequence; - - case CTSF_ROWPCT_COUNT: - case CTSF_COLPCT_COUNT: - case CTSF_TABLEPCT_COUNT: - case CTSF_SUBTABLEPCT_COUNT: - case CTSF_LAYERPCT_COUNT: - case CTSF_LAYERROWPCT_COUNT: - case CTSF_LAYERCOLPCT_COUNT: - { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->e_count - ? s->count / cell->domains[d]->e_count * 100 - : SYSMIS); - } + case CTSF_areaID: + return cell->areas[ss->calc_area]->sequence; - case CTSF_UROWPCT_COUNT: - case CTSF_UCOLPCT_COUNT: - case CTSF_UTABLEPCT_COUNT: - case CTSF_USUBTABLEPCT_COUNT: - case CTSF_ULAYERPCT_COUNT: - case CTSF_ULAYERROWPCT_COUNT: - case CTSF_ULAYERCOLPCT_COUNT: + case CTSF_areaPCT_COUNT: { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->u_count - ? s->count / cell->domains[d]->u_count * 100 - : SYSMIS); + const struct ctables_area *a = cell->areas[ss->calc_area]; + double a_count = ss->weighted ? a->e_count : a->u_count; + return a_count ? s->count / a_count * 100 : SYSMIS; } - case CTSF_ROWPCT_VALIDN: - case CTSF_COLPCT_VALIDN: - case CTSF_TABLEPCT_VALIDN: - case CTSF_SUBTABLEPCT_VALIDN: - case CTSF_LAYERPCT_VALIDN: - case CTSF_LAYERROWPCT_VALIDN: - case CTSF_LAYERCOLPCT_VALIDN: + case CTSF_areaPCT_VALIDN: { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->e_valid - ? s->count / cell->domains[d]->e_valid * 100 - : SYSMIS); + const struct ctables_area *a = cell->areas[ss->calc_area]; + double a_valid = ss->weighted ? a->e_valid : a->u_valid; + return a_valid ? s->count / a_valid * 100 : SYSMIS; } - case CTSF_UROWPCT_VALIDN: - case CTSF_UCOLPCT_VALIDN: - case CTSF_UTABLEPCT_VALIDN: - case CTSF_USUBTABLEPCT_VALIDN: - case CTSF_ULAYERPCT_VALIDN: - case CTSF_ULAYERROWPCT_VALIDN: - case CTSF_ULAYERCOLPCT_VALIDN: + case CTSF_areaPCT_TOTALN: { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->u_valid - ? s->count / cell->domains[d]->u_valid * 100 - : SYSMIS); - } - - case CTSF_ROWPCT_TOTALN: - case CTSF_COLPCT_TOTALN: - case CTSF_TABLEPCT_TOTALN: - case CTSF_SUBTABLEPCT_TOTALN: - case CTSF_LAYERPCT_TOTALN: - case CTSF_LAYERROWPCT_TOTALN: - case CTSF_LAYERCOLPCT_TOTALN: - { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->e_total - ? s->count / cell->domains[d]->e_total * 100 - : SYSMIS); - } - - case CTSF_UROWPCT_TOTALN: - case CTSF_UCOLPCT_TOTALN: - case CTSF_UTABLEPCT_TOTALN: - case CTSF_USUBTABLEPCT_TOTALN: - case CTSF_ULAYERPCT_TOTALN: - case CTSF_ULAYERROWPCT_TOTALN: - case CTSF_ULAYERCOLPCT_TOTALN: - { - enum ctables_domain_type d = ctables_function_domain (ss->function); - return (cell->domains[d]->u_total - ? s->count / cell->domains[d]->u_total * 100 - : SYSMIS); + const struct ctables_area *a = cell->areas[ss->calc_area]; + double a_total = ss->weighted ? a->e_total : a->u_total; + return a_total ? s->count / a_total * 100 : SYSMIS; } case CTSF_MISSING: - case CTSF_UMISSING: - case CSTF_TOTALN: + case CTSF_TOTALN: case CTSF_ETOTALN: - case CSTF_UTOTALN: case CTSF_VALIDN: - case CTSF_UVALIDN: case CTSF_EVALIDN: return s->count; @@ -3125,7 +2787,6 @@ ctables_summary_value (const struct ctables_cell *cell, return s->max != SYSMIS && s->min != SYSMIS ? s->max - s->min : SYSMIS; case CTSF_MEAN: - case CTSF_UMEAN: { double mean; moments1_calculate (s->moments, NULL, &mean, NULL, NULL, NULL); @@ -3133,7 +2794,6 @@ ctables_summary_value (const struct ctables_cell *cell, } case CTSF_SEMEAN: - case CTSF_USEMEAN: { double weight, variance; moments1_calculate (s->moments, &weight, NULL, &variance, NULL, NULL); @@ -3141,7 +2801,6 @@ ctables_summary_value (const struct ctables_cell *cell, } case CTSF_STDDEV: - case CTSF_USTDDEV: { double variance; moments1_calculate (s->moments, NULL, NULL, &variance, NULL, NULL); @@ -3149,7 +2808,6 @@ ctables_summary_value (const struct ctables_cell *cell, } case CTSF_SUM: - case CTSF_USUM: { double weight, mean; moments1_calculate (s->moments, &weight, &mean, NULL, NULL, NULL); @@ -3157,52 +2815,27 @@ ctables_summary_value (const struct ctables_cell *cell, } case CTSF_VARIANCE: - case CTSF_UVARIANCE: { double variance; moments1_calculate (s->moments, NULL, NULL, &variance, NULL, NULL); return variance; } - case CTSF_ROWPCT_SUM: - case CTSF_COLPCT_SUM: - case CTSF_TABLEPCT_SUM: - case CTSF_SUBTABLEPCT_SUM: - case CTSF_LAYERPCT_SUM: - case CTSF_LAYERROWPCT_SUM: - case CTSF_LAYERCOLPCT_SUM: - { - double weight, mean; - moments1_calculate (s->moments, &weight, &mean, NULL, NULL, NULL); - if (weight == SYSMIS || mean == SYSMIS) - return SYSMIS; - enum ctables_domain_type d = ctables_function_domain (ss->function); - double num = weight * mean; - double denom = cell->domains[d]->sums[ss->sum_var_idx].e_sum; - return denom != 0 ? num / denom * 100 : SYSMIS; - } - case CTSF_UROWPCT_SUM: - case CTSF_UCOLPCT_SUM: - case CTSF_UTABLEPCT_SUM: - case CTSF_USUBTABLEPCT_SUM: - case CTSF_ULAYERPCT_SUM: - case CTSF_ULAYERROWPCT_SUM: - case CTSF_ULAYERCOLPCT_SUM: + case CTSF_areaPCT_SUM: { double weight, mean; moments1_calculate (s->moments, &weight, &mean, NULL, NULL, NULL); if (weight == SYSMIS || mean == SYSMIS) return SYSMIS; - enum ctables_domain_type d = ctables_function_domain (ss->function); - double num = weight * mean; - double denom = cell->domains[d]->sums[ss->sum_var_idx].u_sum; - return denom != 0 ? num / denom * 100 : SYSMIS; + + const struct ctables_area *a = cell->areas[ss->calc_area]; + const struct ctables_sum *sum = &a->sums[ss->sum_var_idx]; + double denom = ss->weighted ? sum->e_sum : sum->u_sum; + return denom != 0 ? weight * mean / denom * 100 : SYSMIS; } case CTSF_MEDIAN: case CTSF_PTILE: - case CTSF_UMEDIAN: - case CTSF_UPTILE: if (s->writer) { struct casereader *reader = casewriter_make_reader (s->writer); @@ -3218,7 +2851,6 @@ ctables_summary_value (const struct ctables_cell *cell, return s->ovalue; case CTSF_MODE: - case CTSF_UMODE: if (s->writer) { struct casereader *reader = casewriter_make_reader (s->writer); @@ -3359,17 +2991,17 @@ ctables_cell_compare_leaf_3way (const void *a_, const void *b_, Fill the table entry using the indexes from before. */ -static struct ctables_domain * -ctables_domain_insert (struct ctables_section *s, struct ctables_cell *cell, - enum ctables_domain_type domain) +static struct ctables_area * +ctables_area_insert (struct ctables_section *s, struct ctables_cell *cell, + enum ctables_area_type area) { size_t hash = 0; for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++) { const struct ctables_nest *nest = s->nests[a]; - for (size_t i = 0; i < nest->n_domains[domain]; i++) + for (size_t i = 0; i < nest->n_areas[area]; i++) { - size_t v_idx = nest->domains[domain][i]; + size_t v_idx = nest->areas[area][i]; struct ctables_cell_value *cv = &cell->axes[a].cvs[v_idx]; hash = hash_pointer (cv->category, hash); if (cv->category->type != CCT_TOTAL @@ -3380,16 +3012,16 @@ ctables_domain_insert (struct ctables_section *s, struct ctables_cell *cell, } } - struct ctables_domain *d; - HMAP_FOR_EACH_WITH_HASH (d, struct ctables_domain, node, hash, &s->domains[domain]) + struct ctables_area *a; + HMAP_FOR_EACH_WITH_HASH (a, struct ctables_area, node, hash, &s->areas[area]) { - const struct ctables_cell *df = d->example; + const struct ctables_cell *df = a->example; for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++) { const struct ctables_nest *nest = s->nests[a]; - for (size_t i = 0; i < nest->n_domains[domain]; i++) + for (size_t i = 0; i < nest->n_areas[area]; i++) { - size_t v_idx = nest->domains[domain][i]; + size_t v_idx = nest->areas[area][i]; struct ctables_cell_value *cv1 = &df->axes[a].cvs[v_idx]; struct ctables_cell_value *cv2 = &cell->axes[a].cvs[v_idx]; if (cv1->category != cv2->category @@ -3401,7 +3033,7 @@ ctables_domain_insert (struct ctables_section *s, struct ctables_cell *cell, goto not_equal; } } - return d; + return a; not_equal: ; } @@ -3410,10 +3042,10 @@ ctables_domain_insert (struct ctables_section *s, struct ctables_cell *cell, ? xzalloc (s->table->n_sum_vars * sizeof *sums) : NULL); - d = xmalloc (sizeof *d); - *d = (struct ctables_domain) { .example = cell, .sums = sums }; - hmap_insert (&s->domains[domain], &d->node, hash); - return d; + a = xmalloc (sizeof *a); + *a = (struct ctables_area) { .example = cell, .sums = sums }; + hmap_insert (&s->areas[area], &a->node, hash); + return a; } static struct substring @@ -3558,7 +3190,7 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c, cell = xmalloc (sizeof *cell); cell->hide = false; cell->sv = sv; - cell->omit_domains = 0; + cell->omit_areas = 0; cell->postcompute = false; //struct string name = DS_EMPTY_INITIALIZER; for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++) @@ -3587,22 +3219,22 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c, switch (a) { case PIVOT_AXIS_COLUMN: - cell->omit_domains |= ((1u << CTDT_TABLE) | - (1u << CTDT_LAYER) | - (1u << CTDT_LAYERCOL) | - (1u << CTDT_SUBTABLE) | - (1u << CTDT_COL)); + cell->omit_areas |= ((1u << CTAT_TABLE) | + (1u << CTAT_LAYER) | + (1u << CTAT_LAYERCOL) | + (1u << CTAT_SUBTABLE) | + (1u << CTAT_COL)); break; case PIVOT_AXIS_ROW: - cell->omit_domains |= ((1u << CTDT_TABLE) | - (1u << CTDT_LAYER) | - (1u << CTDT_LAYERROW) | - (1u << CTDT_SUBTABLE) | - (1u << CTDT_ROW)); + cell->omit_areas |= ((1u << CTAT_TABLE) | + (1u << CTAT_LAYER) | + (1u << CTAT_LAYERROW) | + (1u << CTAT_SUBTABLE) | + (1u << CTAT_ROW)); break; case PIVOT_AXIS_LAYER: - cell->omit_domains |= ((1u << CTDT_TABLE) | - (1u << CTDT_LAYER)); + cell->omit_areas |= ((1u << CTAT_TABLE) | + (1u << CTAT_LAYER)); break; } } @@ -3640,8 +3272,8 @@ ctables_cell_insert__ (struct ctables_section *s, const struct ccase *c, cell->summaries = xmalloc (specs->n * sizeof *cell->summaries); for (size_t i = 0; i < specs->n; i++) ctables_summary_init (&cell->summaries[i], &specs->specs[i]); - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) - cell->domains[dt] = ctables_domain_insert (s, cell, dt); + for (enum ctables_area_type at = 0; at < N_CTATS; at++) + cell->areas[at] = ctables_area_insert (s, cell, at); hmap_insert (&s->cells, &cell->node, hash); return cell; } @@ -3683,24 +3315,24 @@ ctables_cell_add__ (struct ctables_section *s, const struct ccase *c, specs->var, case_data (c, specs->var), specs->is_scale, scale_missing, is_missing, excluded_missing, d_weight, e_weight); - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) - if (!(cell->omit_domains && (1u << dt))) + for (enum ctables_area_type at = 0; at < N_CTATS; at++) + if (!(cell->omit_areas && (1u << at))) { - struct ctables_domain *d = cell->domains[dt]; - d->d_total += d_weight; - d->e_total += e_weight; - d->u_total += 1.0; + struct ctables_area *a = cell->areas[at]; + a->d_total += d_weight; + a->e_total += e_weight; + a->u_total += 1.0; if (!excluded_missing) { - d->d_count += d_weight; - d->e_count += e_weight; - d->u_count += 1.0; + a->d_count += d_weight; + a->e_count += e_weight; + a->u_count += 1.0; } if (!is_missing) { - d->d_valid += d_weight; - d->e_valid += e_weight; - d->u_count += 1.0; + a->d_valid += d_weight; + a->e_valid += e_weight; + a->u_count += 1.0; for (size_t i = 0; i < s->table->n_sum_vars; i++) { @@ -3709,7 +3341,7 @@ ctables_cell_add__ (struct ctables_section *s, const struct ccase *c, double addend = case_num (c, var); if (!var_is_num_missing (var, addend)) { - struct ctables_sum *sum = &d->sums[i]; + struct ctables_sum *sum = &a->sums[i]; sum->e_sum += addend * e_weight; sum->u_sum += addend; } @@ -3886,6 +3518,10 @@ merge_item_compare_3way (const struct merge_item *a, const struct merge_item *b) const struct ctables_summary_spec *bs = &b->set->specs[b->ofs]; if (as->function != bs->function) return as->function > bs->function ? 1 : -1; + else if (as->weighted != bs->weighted) + return as->weighted > bs->weighted ? 1 : -1; + else if (as->calc_area != bs->calc_area) + return as->calc_area > bs->calc_area ? 1 : -1; else if (as->percentile != bs->percentile) return as->percentile < bs->percentile ? 1 : -1; @@ -4089,8 +3725,8 @@ ctables_table_add_section (struct ctables_table *t, enum pivot_axis_type a, for (size_t i = 0; i < nest->n; i++) hmap_init (&s->occurrences[a][i]); } - for (size_t i = 0; i < N_CTDTS; i++) - hmap_init (&s->domains[i]); + for (size_t i = 0; i < N_CTATS; i++) + hmap_init (&s->areas[i]); } } @@ -4380,6 +4016,8 @@ ctables_cell_calculate_postcompute (const struct ctables_section *s, { const struct ctables_summary_spec *ss2 = &pc->specs->specs[i]; if (ss->function == ss2->function + && ss->weighted == ss2->weighted + && ss->calc_area == ss2->calc_area && ss->percentile == ss2->percentile) { *format = ss2->format; @@ -4562,16 +4200,16 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) #if 0 if (a == PIVOT_AXIS_ROW) { - size_t ids[N_CTDTS]; + size_t ids[N_CTATS]; memset (ids, 0, sizeof ids); for (size_t j = 0; j < n_sorted; j++) { struct ctables_cell *cell = sorted[j]; - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) + for (enum ctables_area_type at = 0; at < N_CTATS; at++) { - struct ctables_domain *domain = cell->domains[dt]; - if (!domain->sequence) - domain->sequence = ++ids[dt]; + struct ctables_area *area = cell->areas[at]; + if (!area->sequence) + area->sequence = ++ids[at]; } } } @@ -4580,7 +4218,7 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) #if 0 for (size_t j = 0; j < n_sorted; j++) { - printf ("%s (%s): %f/%f = %.1f%%\n", sorted[j]->name, sorted[j]->contributes_to_domains ? "y" : "n", sorted[j]->summaries[0].count, sorted[j]->domains[CTDT_COL]->e_count, sorted[j]->summaries[0].count / sorted[j]->domains[CTDT_COL]->e_count * 100.0); + printf ("%s (%s): %f/%f = %.1f%%\n", sorted[j]->name, sorted[j]->contributes_to_areas ? "y" : "n", sorted[j]->summaries[0].count, sorted[j]->areas[CTAT_COL]->e_count, sorted[j]->summaries[0].count / sorted[j]->areas[CTAT_COL]->e_count * 100.0); } printf ("\n"); #endif @@ -4757,16 +4395,16 @@ ctables_table_output (struct ctables *ct, struct ctables_table *t) assert (n_sorted <= n_total_cells); sort (sorted, n_sorted, sizeof *sorted, ctables_cell_compare_leaf_3way, NULL); - size_t ids[N_CTDTS]; + size_t ids[N_CTATS]; memset (ids, 0, sizeof ids); for (size_t j = 0; j < n_sorted; j++) { struct ctables_cell *cell = sorted[j]; - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) + for (enum ctables_area_type at = 0; at < N_CTATS; at++) { - struct ctables_domain *domain = cell->domains[dt]; - if (!domain->sequence) - domain->sequence = ++ids[dt]; + struct ctables_area *area = cell->areas[at]; + if (!area->sequence) + area->sequence = ++ids[at]; } } @@ -4958,6 +4596,33 @@ add_sum_var (struct variable *var, return (*n)++; } +static enum ctables_area_type +rotate_area (enum ctables_area_type area) +{ + return area; + switch (area) + { + case CTAT_TABLE: + case CTAT_LAYER: + case CTAT_SUBTABLE: + return area; + + case CTAT_LAYERROW: + return CTAT_LAYERCOL; + + case CTAT_LAYERCOL: + return CTAT_LAYERROW; + + case CTAT_ROW: + return CTAT_COL; + + case CTAT_COL: + return CTAT_ROW; + } + + NOT_REACHED (); +} + static void enumerate_sum_vars (const struct ctables_axis *a, struct variable ***sum_vars, size_t *n, size_t *allocated) @@ -4972,7 +4637,7 @@ enumerate_sum_vars (const struct ctables_axis *a, for (size_t j = 0; j < a->specs[i].n; j++) { struct ctables_summary_spec *spec = &a->specs[i].specs[j]; - if (ctables_function_is_pctsum (spec->function)) + if (spec->function == CTSF_areaPCT_SUM) spec->sum_var_idx = add_sum_var (a->var, sum_vars, n, allocated); } break; @@ -4996,53 +4661,150 @@ ctables_prepare_table (struct ctables_table *t) for (size_t j = 0; j < t->stacks[a].n; j++) { struct ctables_nest *nest = &t->stacks[a].nests[j]; - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) + for (enum ctables_area_type at = 0; at < N_CTATS; at++) { - nest->domains[dt] = xmalloc (nest->n * sizeof *nest->domains[dt]); - nest->n_domains[dt] = 0; - - for (size_t k = 0; k < nest->n; k++) + nest->areas[at] = xmalloc (nest->n * sizeof *nest->areas[at]); + nest->n_areas[at] = 0; + + bool add_vars = (at == CTAT_LAYER ? a == PIVOT_AXIS_LAYER + : at == CTAT_LAYERROW ? a != PIVOT_AXIS_COLUMN + : at == CTAT_LAYERCOL ? a != PIVOT_AXIS_ROW + : at == CTAT_TABLE ? false + : true); + if (add_vars) + for (size_t k = 0; k < nest->n; k++) + { + if (k == nest->scale_idx) + continue; + nest->areas[at][nest->n_areas[at]++] = k; + } + else if ((at == CTAT_LAYERCOL && a == PIVOT_AXIS_ROW && t->label_axis[a] != a) + || (at == CTAT_LAYERROW && a == PIVOT_AXIS_COLUMN && t->label_axis[a] != a) + || (at == CTAT_LAYER && t->label_axis[a] == PIVOT_AXIS_LAYER)) { - if (k == nest->scale_idx) - continue; - - switch (dt) + for (size_t k = nest->n - 1; k < nest->n; k--) { - case CTDT_TABLE: - continue; - - case CTDT_LAYER: - if (a != PIVOT_AXIS_LAYER) + if (k == nest->scale_idx) continue; + nest->areas[at][nest->n_areas[at]++] = k; break; + } + continue; + } - case CTDT_SUBTABLE: - case CTDT_ROW: - case CTDT_COL: - if (dt == CTDT_SUBTABLE ? a != PIVOT_AXIS_LAYER - : dt == CTDT_ROW ? a == PIVOT_AXIS_COLUMN - : a == PIVOT_AXIS_ROW) + size_t n_drop; + if (at == CTAT_SUBTABLE && t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_COLUMN) + { + n_drop = (a == PIVOT_AXIS_LAYER ? 0 + : a == PIVOT_AXIS_ROW ? 2 + : 0); + } + else if (at == CTAT_SUBTABLE && t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_ROW) + { + n_drop = (a == PIVOT_AXIS_LAYER ? 0 + : a == PIVOT_AXIS_COLUMN ? 2 + : 0); + } + else if (at == CTAT_SUBTABLE && t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_LAYER) + { + if (a == PIVOT_AXIS_COLUMN) + n_drop = 1; + else + { + if (a == PIVOT_AXIS_ROW) { - if (k == nest->n - 1 - || (nest->scale_idx == nest->n - 1 - && k == nest->n - 2)) - continue; + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } } - break; - - case CTDT_LAYERROW: + n_drop = 0; + } + } + else if (at == CTAT_SUBTABLE && t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_LAYER) + { + if (a == PIVOT_AXIS_ROW) + n_drop = 1; + else + { if (a == PIVOT_AXIS_COLUMN) - continue; - break; - - case CTDT_LAYERCOL: - if (a == PIVOT_AXIS_ROW) - continue; - break; + { + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } + } + n_drop = 0; } - - nest->domains[dt][nest->n_domains[dt]++] = k; } + else if (at == CTAT_ROW && a == PIVOT_AXIS_COLUMN && t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_COLUMN) + n_drop = 0; + else if (at == CTAT_COL && a == PIVOT_AXIS_ROW && t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_COLUMN) + { + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } + n_drop = 0; + } + else if (at == CTAT_COL && a == PIVOT_AXIS_ROW && t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_ROW) + continue; + else if (at == CTAT_ROW && a == PIVOT_AXIS_COLUMN && t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_ROW) + { + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } + n_drop = 0; + } + else if (at == CTAT_COL && a == PIVOT_AXIS_ROW && t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_LAYER) + { + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } + n_drop = 0; + } + else if (at == CTAT_ROW && a == PIVOT_AXIS_COLUMN && t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_LAYER) + { + size_t n = nest->n_areas[at]; + if (n > 1) + { + nest->areas[at][n - 2] = nest->areas[at][n - 1]; + nest->n_areas[at]--; + } + n_drop = 0; + } + else + { + bool drop_last = (at == CTAT_SUBTABLE ? a != PIVOT_AXIS_LAYER + : at == CTAT_ROW ? a == PIVOT_AXIS_COLUMN + : at == CTAT_COL ? a == PIVOT_AXIS_ROW + : false); + bool drop_additional + = ((t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_COLUMN && (at == CTAT_ROW || at == CTAT_LAYERROW) && a == PIVOT_AXIS_ROW) + || (t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_ROW && (at == CTAT_COL || at == CTAT_LAYERCOL) && a == PIVOT_AXIS_COLUMN)); + + n_drop = 0; + if (drop_last) + n_drop++; + if (drop_additional) + n_drop++; + } + + for (size_t i = 0; i < n_drop; i++) + if (nest->n_areas[at] > 0) + nest->n_areas[at]--; } } } @@ -5072,6 +4834,7 @@ ctables_prepare_table (struct ctables_table *t) *specs->specs = (struct ctables_summary_spec) { .function = function, + .weighted = true, .format = ctables_summary_default_format (function, specs->var), }; if (!specs->var) @@ -5084,6 +4847,20 @@ ctables_prepare_table (struct ctables_table *t) ctables_summary_spec_set_clone (&nest->specs[CSV_TOTAL], &nest->specs[CSV_CELL]); + if (t->label_axis[PIVOT_AXIS_ROW] == PIVOT_AXIS_COLUMN + || t->label_axis[PIVOT_AXIS_COLUMN] == PIVOT_AXIS_ROW) + { + for (enum ctables_summary_variant sv = 0; sv < N_CSVS; sv++) + for (size_t i = 0; i < nest->specs[sv].n; i++) + { + struct ctables_summary_spec *ss = &nest->specs[sv].specs[i]; + const struct ctables_function_info *cfi = + &ctables_function_info[ss->function]; + if (cfi->is_area) + ss->calc_area = rotate_area (ss->calc_area); + } + } + if (t->ctables->smissing_listwise) { struct variable **listwise_vars = NULL; @@ -5440,17 +5217,17 @@ ctables_section_clear (struct ctables_section *s) } hmap_shrink (&s->cells); - for (enum ctables_domain_type dt = 0; dt < N_CTDTS; dt++) + for (enum ctables_area_type at = 0; at < N_CTATS; at++) { - struct ctables_domain *domain, *next_domain; - HMAP_FOR_EACH_SAFE (domain, next_domain, struct ctables_domain, node, - &s->domains[dt]) + struct ctables_area *area, *next_area; + HMAP_FOR_EACH_SAFE (area, next_area, struct ctables_area, node, + &s->areas[at]) { - free (domain->sums); - hmap_delete (&s->domains[dt], &domain->node); - free (domain); + free (area->sums); + hmap_delete (&s->areas[at], &area->node); + free (area); } - hmap_shrink (&s->domains[dt]); + hmap_shrink (&s->areas[at]); } } @@ -5468,8 +5245,8 @@ ctables_section_uninit (struct ctables_section *s) } hmap_destroy (&s->cells); - for (size_t i = 0; i < N_CTDTS; i++) - hmap_destroy (&s->domains[i]); + for (size_t i = 0; i < N_CTATS; i++) + hmap_destroy (&s->areas[i]); } static void @@ -6046,7 +5823,9 @@ ctables_parse_pproperties_format (struct lexer *lexer, { /* Parse function. */ enum ctables_summary_function function; - if (!parse_ctables_summary_function (lexer, &function)) + bool weighted; + enum ctables_area_type area; + if (!parse_ctables_summary_function (lexer, &function, &weighted, &area)) goto error; /* Parse percentile. */ @@ -6070,6 +5849,9 @@ ctables_parse_pproperties_format (struct lexer *lexer, sizeof *sss->specs); sss->specs[sss->n++] = (struct ctables_summary_spec) { .function = function, + .weighted = weighted, + .calc_area = area, + .user_area = area, .percentile = percentile, .format = format, .is_ctables_format = is_ctables_format,