1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include <data/any-writer.h>
24 #include <data/case-sink.h>
25 #include <data/case.h>
26 #include <data/casefile.h>
27 #include <data/dictionary.h>
28 #include <data/file-handle-def.h>
29 #include <data/format.h>
30 #include <data/procedure.h>
31 #include <data/settings.h>
32 #include <data/storage-stream.h>
33 #include <data/sys-file-writer.h>
34 #include <data/variable.h>
35 #include <language/command.h>
36 #include <language/data-io/file-handle.h>
37 #include <language/lexer/lexer.h>
38 #include <language/lexer/variable-parser.h>
39 #include <language/stats/sort-criteria.h>
40 #include <libpspp/alloc.h>
41 #include <libpspp/assertion.h>
42 #include <libpspp/message.h>
43 #include <libpspp/misc.h>
44 #include <libpspp/pool.h>
45 #include <libpspp/str.h>
46 #include <math/moments.h>
47 #include <math/sort.h>
52 #define _(msgid) gettext (msgid)
54 /* Argument for AGGREGATE function. */
57 double f; /* Numeric. */
58 char *c; /* Short or long string. */
61 /* Specifies how to make an aggregate variable. */
64 struct agr_var *next; /* Next in list. */
66 /* Collected during parsing. */
67 struct variable *src; /* Source variable. */
68 struct variable *dest; /* Target variable. */
69 int function; /* Function. */
70 enum mv_class exclude; /* Classes of missing values to exclude. */
71 union agr_argument arg[2]; /* Arguments. */
73 /* Accumulated during AGGREGATE execution. */
78 struct moments1 *moments;
81 /* Aggregation functions. */
84 NONE, SUM, MEAN, SD, MAX, MIN, PGT, PLT, PIN, POUT, FGT, FLT, FIN,
85 FOUT, N, NU, NMISS, NUMISS, FIRST, LAST,
86 N_AGR_FUNCS, N_NO_VARS, NU_NO_VARS,
87 FUNC = 0x1f, /* Function mask. */
88 FSTRING = 1<<5, /* String function bit. */
91 /* Attributes of an aggregation function. */
94 const char *name; /* Aggregation function name. */
95 size_t n_args; /* Number of arguments. */
96 enum var_type alpha_type; /* When given ALPHA arguments, output type. */
97 struct fmt_spec format; /* Format spec if alpha_type != ALPHA. */
100 /* Attributes of aggregation functions. */
101 static const struct agr_func agr_func_tab[] =
103 {"<NONE>", 0, -1, {0, 0, 0}},
104 {"SUM", 0, -1, {FMT_F, 8, 2}},
105 {"MEAN", 0, -1, {FMT_F, 8, 2}},
106 {"SD", 0, -1, {FMT_F, 8, 2}},
107 {"MAX", 0, VAR_STRING, {-1, -1, -1}},
108 {"MIN", 0, VAR_STRING, {-1, -1, -1}},
109 {"PGT", 1, VAR_NUMERIC, {FMT_F, 5, 1}},
110 {"PLT", 1, VAR_NUMERIC, {FMT_F, 5, 1}},
111 {"PIN", 2, VAR_NUMERIC, {FMT_F, 5, 1}},
112 {"POUT", 2, VAR_NUMERIC, {FMT_F, 5, 1}},
113 {"FGT", 1, VAR_NUMERIC, {FMT_F, 5, 3}},
114 {"FLT", 1, VAR_NUMERIC, {FMT_F, 5, 3}},
115 {"FIN", 2, VAR_NUMERIC, {FMT_F, 5, 3}},
116 {"FOUT", 2, VAR_NUMERIC, {FMT_F, 5, 3}},
117 {"N", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
118 {"NU", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
119 {"NMISS", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
120 {"NUMISS", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
121 {"FIRST", 0, VAR_STRING, {-1, -1, -1}},
122 {"LAST", 0, VAR_STRING, {-1, -1, -1}},
123 {NULL, 0, -1, {-1, -1, -1}},
124 {"N", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
125 {"NU", 0, VAR_NUMERIC, {FMT_F, 7, 0}},
128 /* Missing value types. */
129 enum missing_treatment
131 ITEMWISE, /* Missing values item by item. */
132 COLUMNWISE /* Missing values column by column. */
135 /* An entire AGGREGATE procedure. */
138 /* We have either an output file or a sink. */
139 struct any_writer *writer; /* Output file, or null if none. */
140 struct case_sink *sink; /* Sink, or null if none. */
142 /* Break variables. */
143 struct sort_criteria *sort; /* Sort criteria. */
144 struct variable **break_vars; /* Break variables. */
145 size_t break_var_cnt; /* Number of break variables. */
146 struct ccase break_case; /* Last values of break variables. */
148 enum missing_treatment missing; /* How to treat missing values. */
149 struct agr_var *agr_vars; /* First aggregate variable. */
150 struct dictionary *dict; /* Aggregate dictionary. */
151 const struct dictionary *src_dict; /* Dict of the source */
152 int case_cnt; /* Counts aggregated cases. */
153 struct ccase agr_case; /* Aggregate case for output. */
156 static void initialize_aggregate_info (struct agr_proc *,
157 const struct ccase *);
160 static bool parse_aggregate_functions (struct lexer *, const struct dictionary *,
162 static void agr_destroy (struct agr_proc *);
163 static bool aggregate_single_case (struct agr_proc *agr,
164 const struct ccase *input,
165 struct ccase *output);
166 static void dump_aggregate_info (struct agr_proc *agr, struct ccase *output);
170 /* Parses and executes the AGGREGATE procedure. */
172 cmd_aggregate (struct lexer *lexer, struct dataset *ds)
174 struct dictionary *dict = dataset_dict (ds);
176 struct file_handle *out_file = NULL;
178 bool copy_documents = false;
179 bool presorted = false;
182 memset(&agr, 0 , sizeof (agr));
183 agr.missing = ITEMWISE;
184 case_nullify (&agr.break_case);
186 agr.dict = dict_create ();
188 dict_set_label (agr.dict, dict_get_label (dict));
189 dict_set_documents (agr.dict, dict_get_documents (dict));
191 /* OUTFILE subcommand must be first. */
192 if (!lex_force_match_id (lexer, "OUTFILE"))
194 lex_match (lexer, '=');
195 if (!lex_match (lexer, '*'))
197 out_file = fh_parse (lexer, FH_REF_FILE | FH_REF_SCRATCH);
198 if (out_file == NULL)
202 /* Read most of the subcommands. */
205 lex_match (lexer, '/');
207 if (lex_match_id (lexer, "MISSING"))
209 lex_match (lexer, '=');
210 if (!lex_match_id (lexer, "COLUMNWISE"))
212 lex_error (lexer, _("while expecting COLUMNWISE"));
215 agr.missing = COLUMNWISE;
217 else if (lex_match_id (lexer, "DOCUMENT"))
218 copy_documents = true;
219 else if (lex_match_id (lexer, "PRESORTED"))
221 else if (lex_match_id (lexer, "BREAK"))
225 lex_match (lexer, '=');
226 agr.sort = sort_parse_criteria (lexer, dict,
227 &agr.break_vars, &agr.break_var_cnt,
228 &saw_direction, NULL);
229 if (agr.sort == NULL)
232 for (i = 0; i < agr.break_var_cnt; i++)
233 dict_clone_var_assert (agr.dict, agr.break_vars[i],
234 var_get_name (agr.break_vars[i]));
236 /* BREAK must follow the options. */
241 lex_error (lexer, _("expecting BREAK"));
245 if (presorted && saw_direction)
246 msg (SW, _("When PRESORTED is specified, specifying sorting directions "
247 "with (A) or (D) has no effect. Output data will be sorted "
248 "the same way as the input data."));
250 /* Read in the aggregate functions. */
251 lex_match (lexer, '/');
252 if (!parse_aggregate_functions (lexer, dict, &agr))
255 /* Delete documents. */
257 dict_set_documents (agr.dict, NULL);
259 /* Cancel SPLIT FILE. */
260 dict_set_split_vars (agr.dict, NULL, 0);
264 case_create (&agr.agr_case, dict_get_next_value_idx (agr.dict));
266 /* Output to active file or external file? */
267 if (out_file == NULL)
271 /* The active file will be replaced by the aggregated data,
272 so TEMPORARY is moot. */
273 proc_cancel_temporary_transformations (ds);
275 if (agr.sort != NULL && !presorted)
277 if (!sort_active_file_in_place (ds, agr.sort))
281 agr.sink = create_case_sink (&storage_sink_class, agr.dict,
282 dataset_get_casefile_factory (ds),
284 if (agr.sink->class->open != NULL)
285 agr.sink->class->open (agr.sink);
287 create_case_sink (&null_sink_class, dict,
288 dataset_get_casefile_factory (ds),
291 while (proc_read (ds, &c))
292 if (aggregate_single_case (&agr, c, &agr.agr_case))
293 if (!agr.sink->class->write (agr.sink, &agr.agr_case))
298 if (!proc_close (ds))
301 if (agr.case_cnt > 0)
303 dump_aggregate_info (&agr, &agr.agr_case);
304 if (!agr.sink->class->write (agr.sink, &agr.agr_case))
307 discard_variables (ds);
308 dataset_set_dict (ds, agr.dict);
310 proc_set_source (ds, agr.sink->class->make_source (agr.sink));
311 free_case_sink (agr.sink);
315 agr.writer = any_writer_open (out_file, agr.dict);
316 if (agr.writer == NULL)
319 if (agr.sort != NULL && !presorted)
321 /* Sorting is needed. */
322 struct casefile *dst;
323 struct casereader *reader;
327 dst = sort_active_file_to_casefile (ds, agr.sort);
330 reader = casefile_get_destructive_reader (dst);
331 while (ok && casereader_read_xfer (reader, &c))
333 if (aggregate_single_case (&agr, &c, &agr.agr_case))
334 ok = any_writer_write (agr.writer, &agr.agr_case);
337 casereader_destroy (reader);
339 ok = !casefile_error (dst);
340 casefile_destroy (dst);
346 /* Active file is already sorted. */
350 while (proc_read (ds, &c))
351 if (aggregate_single_case (&agr, c, &agr.agr_case))
352 if (!any_writer_write (agr.writer, &agr.agr_case))
357 if (!proc_close (ds))
361 if (agr.case_cnt > 0)
363 dump_aggregate_info (&agr, &agr.agr_case);
364 any_writer_write (agr.writer, &agr.agr_case);
366 if (any_writer_error (agr.writer))
375 return CMD_CASCADING_FAILURE;
378 /* Parse all the aggregate functions. */
380 parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, struct agr_proc *agr)
382 struct agr_var *tail; /* Tail of linked list starting at agr->vars. */
384 /* Parse everything. */
391 struct string function_name;
393 enum mv_class exclude;
394 const struct agr_func *function;
397 union agr_argument arg[2];
399 struct variable **src;
413 /* Parse the list of target variables. */
414 while (!lex_match (lexer, '='))
416 size_t n_dest_prev = n_dest;
418 if (!parse_DATA_LIST_vars (lexer, &dest, &n_dest,
419 PV_APPEND | PV_SINGLE | PV_NO_SCRATCH))
422 /* Assign empty labels. */
426 dest_label = xnrealloc (dest_label, n_dest, sizeof *dest_label);
427 for (j = n_dest_prev; j < n_dest; j++)
428 dest_label[j] = NULL;
433 if (lex_token (lexer) == T_STRING)
436 ds_init_string (&label, lex_tokstr (lexer));
438 ds_truncate (&label, 255);
439 dest_label[n_dest - 1] = ds_xstrdup (&label);
445 /* Get the name of the aggregation function. */
446 if (lex_token (lexer) != T_ID)
448 lex_error (lexer, _("expecting aggregation function"));
454 ds_init_string (&function_name, lex_tokstr (lexer));
456 ds_chomp (&function_name, '.');
458 if (lex_tokid(lexer)[strlen (lex_tokid (lexer)) - 1] == '.')
461 for (function = agr_func_tab; function->name; function++)
462 if (!strcasecmp (function->name, ds_cstr (&function_name)))
464 if (NULL == function->name)
466 msg (SE, _("Unknown aggregation function %s."),
467 ds_cstr (&function_name));
470 ds_destroy (&function_name);
471 func_index = function - agr_func_tab;
474 /* Check for leading lparen. */
475 if (!lex_match (lexer, '('))
478 func_index = N_NO_VARS;
479 else if (func_index == NU)
480 func_index = NU_NO_VARS;
483 lex_error (lexer, _("expecting `('"));
489 /* Parse list of source variables. */
491 int pv_opts = PV_NO_SCRATCH;
493 if (func_index == SUM || func_index == MEAN || func_index == SD)
494 pv_opts |= PV_NUMERIC;
495 else if (function->n_args)
496 pv_opts |= PV_SAME_TYPE;
498 if (!parse_variables (lexer, dict, &src, &n_src, pv_opts))
502 /* Parse function arguments, for those functions that
503 require arguments. */
504 if (function->n_args != 0)
505 for (i = 0; i < function->n_args; i++)
509 lex_match (lexer, ',');
510 if (lex_token (lexer) == T_STRING)
512 arg[i].c = ds_xstrdup (lex_tokstr (lexer));
515 else if (lex_is_number (lexer))
517 arg[i].f = lex_tokval (lexer);
522 msg (SE, _("Missing argument %d to %s."), i + 1,
529 if (type != var_get_type (src[0]))
531 msg (SE, _("Arguments to %s must be of same type as "
532 "source variables."),
538 /* Trailing rparen. */
539 if (!lex_match (lexer, ')'))
541 lex_error (lexer, _("expecting `)'"));
545 /* Now check that the number of source variables match
546 the number of target variables. If we check earlier
547 than this, the user can get very misleading error
548 message, i.e. `AGGREGATE x=SUM(y t).' will get this
549 error message when a proper message would be more
550 like `unknown variable t'. */
553 msg (SE, _("Number of source variables (%u) does not match "
554 "number of target variables (%u)."),
555 (unsigned) n_src, (unsigned) n_dest);
559 if ((func_index == PIN || func_index == POUT
560 || func_index == FIN || func_index == FOUT)
561 && (var_is_numeric (src[0])
562 ? arg[0].f > arg[1].f
563 : str_compare_rpad (arg[0].c, arg[1].c) > 0))
565 union agr_argument t = arg[0];
569 msg (SW, _("The value arguments passed to the %s function "
570 "are out-of-order. They will be treated as if "
571 "they had been specified in the correct order."),
576 /* Finally add these to the linked list of aggregation
578 for (i = 0; i < n_dest; i++)
580 struct agr_var *v = xmalloc (sizeof *v);
582 /* Add variable to chain. */
583 if (agr->agr_vars != NULL)
591 /* Create the target variable in the aggregate
594 struct variable *destvar;
596 v->function = func_index;
602 if (var_is_alpha (src[i]))
604 v->function |= FSTRING;
605 v->string = xmalloc (var_get_width (src[i]));
608 if (function->alpha_type == VAR_STRING)
609 destvar = dict_clone_var (agr->dict, v->src, dest[i]);
612 assert (var_is_numeric (v->src)
613 || function->alpha_type == VAR_NUMERIC);
614 destvar = dict_create_var (agr->dict, dest[i], 0);
618 if ((func_index == N || func_index == NMISS)
619 && dict_get_weight (dict) != NULL)
620 f = fmt_for_output (FMT_F, 8, 2);
622 f = function->format;
623 var_set_both_formats (destvar, &f);
629 destvar = dict_create_var (agr->dict, dest[i], 0);
630 if (func_index == N_NO_VARS && dict_get_weight (dict) != NULL)
631 f = fmt_for_output (FMT_F, 8, 2);
633 f = function->format;
634 var_set_both_formats (destvar, &f);
639 msg (SE, _("Variable name %s is not unique within the "
640 "aggregate file dictionary, which contains "
641 "the aggregate variables and the break "
649 var_set_label (destvar, dest_label[i]);
654 v->exclude = exclude;
660 if (var_is_numeric (v->src))
661 for (j = 0; j < function->n_args; j++)
662 v->arg[j].f = arg[j].f;
664 for (j = 0; j < function->n_args; j++)
665 v->arg[j].c = xstrdup (arg[j].c);
669 if (src != NULL && var_is_alpha (src[0]))
670 for (i = 0; i < function->n_args; i++)
680 if (!lex_match (lexer, '/'))
682 if (lex_token (lexer) == '.')
685 lex_error (lexer, "expecting end of command");
691 ds_destroy (&function_name);
692 for (i = 0; i < n_dest; i++)
695 free (dest_label[i]);
701 if (src && n_src && var_is_alpha (src[0]))
702 for (i = 0; i < function->n_args; i++)
715 agr_destroy (struct agr_proc *agr)
717 struct agr_var *iter, *next;
719 any_writer_close (agr->writer);
720 if (agr->sort != NULL)
721 sort_destroy_criteria (agr->sort);
722 free (agr->break_vars);
723 case_destroy (&agr->break_case);
724 for (iter = agr->agr_vars; iter; iter = next)
728 if (iter->function & FSTRING)
733 n_args = agr_func_tab[iter->function & FUNC].n_args;
734 for (i = 0; i < n_args; i++)
735 free (iter->arg[i].c);
738 else if (iter->function == SD)
739 moments1_destroy (iter->moments);
742 if (agr->dict != NULL)
743 dict_destroy (agr->dict);
745 case_destroy (&agr->agr_case);
750 static void accumulate_aggregate_info (struct agr_proc *,
751 const struct ccase *);
752 static void dump_aggregate_info (struct agr_proc *, struct ccase *);
754 /* Processes a single case INPUT for aggregation. If output is
755 warranted, writes it to OUTPUT and returns true.
756 Otherwise, returns false and OUTPUT is unmodified. */
758 aggregate_single_case (struct agr_proc *agr,
759 const struct ccase *input, struct ccase *output)
761 bool finished_group = false;
763 if (agr->case_cnt++ == 0)
764 initialize_aggregate_info (agr, input);
765 else if (case_compare (&agr->break_case, input,
766 agr->break_vars, agr->break_var_cnt))
768 dump_aggregate_info (agr, output);
769 finished_group = true;
771 initialize_aggregate_info (agr, input);
774 accumulate_aggregate_info (agr, input);
775 return finished_group;
778 /* Accumulates aggregation data from the case INPUT. */
780 accumulate_aggregate_info (struct agr_proc *agr,
781 const struct ccase *input)
783 struct agr_var *iter;
785 bool bad_warn = true;
787 weight = dict_get_case_weight (agr->src_dict, input, &bad_warn);
789 for (iter = agr->agr_vars; iter; iter = iter->next)
792 const union value *v = case_data (input, iter->src);
793 int src_width = var_get_width (iter->src);
795 if (var_is_value_missing (iter->src, v, iter->exclude))
797 switch (iter->function)
800 case NMISS | FSTRING:
801 iter->dbl[0] += weight;
804 case NUMISS | FSTRING:
808 iter->saw_missing = true;
812 /* This is horrible. There are too many possibilities. */
813 switch (iter->function)
816 iter->dbl[0] += v->f * weight;
820 iter->dbl[0] += v->f * weight;
821 iter->dbl[1] += weight;
824 moments1_add (iter->moments, v->f, weight);
827 iter->dbl[0] = MAX (iter->dbl[0], v->f);
831 if (memcmp (iter->string, v->s, src_width) < 0)
832 memcpy (iter->string, v->s, src_width);
836 iter->dbl[0] = MIN (iter->dbl[0], v->f);
840 if (memcmp (iter->string, v->s, src_width) > 0)
841 memcpy (iter->string, v->s, src_width);
846 if (v->f > iter->arg[0].f)
847 iter->dbl[0] += weight;
848 iter->dbl[1] += weight;
852 if (memcmp (iter->arg[0].c, v->s, src_width) < 0)
853 iter->dbl[0] += weight;
854 iter->dbl[1] += weight;
858 if (v->f < iter->arg[0].f)
859 iter->dbl[0] += weight;
860 iter->dbl[1] += weight;
864 if (memcmp (iter->arg[0].c, v->s, src_width) > 0)
865 iter->dbl[0] += weight;
866 iter->dbl[1] += weight;
870 if (iter->arg[0].f <= v->f && v->f <= iter->arg[1].f)
871 iter->dbl[0] += weight;
872 iter->dbl[1] += weight;
876 if (memcmp (iter->arg[0].c, v->s, src_width) <= 0
877 && memcmp (iter->arg[1].c, v->s, src_width) >= 0)
878 iter->dbl[0] += weight;
879 iter->dbl[1] += weight;
883 if (iter->arg[0].f > v->f || v->f > iter->arg[1].f)
884 iter->dbl[0] += weight;
885 iter->dbl[1] += weight;
889 if (memcmp (iter->arg[0].c, v->s, src_width) > 0
890 || memcmp (iter->arg[1].c, v->s, src_width) < 0)
891 iter->dbl[0] += weight;
892 iter->dbl[1] += weight;
896 iter->dbl[0] += weight;
909 case FIRST | FSTRING:
912 memcpy (iter->string, v->s, src_width);
921 memcpy (iter->string, v->s, src_width);
925 case NMISS | FSTRING:
927 case NUMISS | FSTRING:
928 /* Our value is not missing or it would have been
929 caught earlier. Nothing to do. */
935 switch (iter->function)
938 iter->dbl[0] += weight;
949 /* We've come to a record that differs from the previous in one or
950 more of the break variables. Make an output record from the
951 accumulated statistics in the OUTPUT case. */
953 dump_aggregate_info (struct agr_proc *agr, struct ccase *output)
959 for (i = 0; i < agr->break_var_cnt; i++)
961 struct variable *v = agr->break_vars[i];
962 size_t value_cnt = var_get_value_cnt (v);
963 memcpy (case_data_rw_idx (output, value_idx),
964 case_data (&agr->break_case, v),
965 sizeof (union value) * value_cnt);
966 value_idx += value_cnt;
973 for (i = agr->agr_vars; i; i = i->next)
975 union value *v = case_data_rw (output, i->dest);
977 if (agr->missing == COLUMNWISE && i->saw_missing
978 && (i->function & FUNC) != N && (i->function & FUNC) != NU
979 && (i->function & FUNC) != NMISS && (i->function & FUNC) != NUMISS)
981 if (var_is_alpha (i->dest))
982 memset (v->s, ' ', var_get_width (i->dest));
991 v->f = i->int1 ? i->dbl[0] : SYSMIS;
994 v->f = i->dbl[1] != 0.0 ? i->dbl[0] / i->dbl[1] : SYSMIS;
1000 /* FIXME: we should use two passes. */
1001 moments1_calculate (i->moments, NULL, NULL, &variance,
1003 if (variance != SYSMIS)
1004 v->f = sqrt (variance);
1011 v->f = i->int1 ? i->dbl[0] : SYSMIS;
1016 memcpy (v->s, i->string, var_get_width (i->dest));
1018 memset (v->s, ' ', var_get_width (i->dest));
1027 case FOUT | FSTRING:
1028 v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] : SYSMIS;
1037 case POUT | FSTRING:
1038 v->f = i->dbl[1] ? i->dbl[0] / i->dbl[1] * 100.0 : SYSMIS;
1050 v->f = i->int1 ? i->dbl[0] : SYSMIS;
1052 case FIRST | FSTRING:
1053 case LAST | FSTRING:
1055 memcpy (v->s, i->string, var_get_width (i->dest));
1057 memset (v->s, ' ', var_get_width (i->dest));
1066 case NMISS | FSTRING:
1070 case NUMISS | FSTRING:
1080 /* Resets the state for all the aggregate functions. */
1082 initialize_aggregate_info (struct agr_proc *agr, const struct ccase *input)
1084 struct agr_var *iter;
1086 case_destroy (&agr->break_case);
1087 case_clone (&agr->break_case, input);
1089 for (iter = agr->agr_vars; iter; iter = iter->next)
1091 iter->saw_missing = false;
1092 iter->dbl[0] = iter->dbl[1] = iter->dbl[2] = 0.0;
1093 iter->int1 = iter->int2 = 0;
1094 switch (iter->function)
1097 iter->dbl[0] = DBL_MAX;
1100 memset (iter->string, 255, var_get_width (iter->src));
1103 iter->dbl[0] = -DBL_MAX;
1106 memset (iter->string, 0, var_get_width (iter->src));
1109 if (iter->moments == NULL)
1110 iter->moments = moments1_create (MOMENT_VARIANCE);
1112 moments1_clear (iter->moments);