1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2011, 2012, 2013, 2019 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU 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, see <http://www.gnu.org/licenses/>. */
19 #include "data/case.h"
20 #include "data/casegrouper.h"
21 #include "data/casereader.h"
22 #include "data/dataset.h"
23 #include "data/dictionary.h"
24 #include "data/format.h"
25 #include "data/variable.h"
27 #include "language/command.h"
28 #include "language/lexer/lexer.h"
29 #include "language/lexer/variable-parser.h"
31 #include "libpspp/hmap.h"
32 #include "libpspp/bt.h"
33 #include "libpspp/misc.h"
34 #include "libpspp/pool.h"
38 /* Parse the /TABLES stanza of the command. */
40 parse_means_table_syntax (struct lexer *lexer, const struct means *cmd,
46 /* Dependent variable (s) */
47 if (!parse_variables_const_pool (lexer, cmd->pool, cmd->dict,
48 &table->dep_vars, &table->n_dep_vars,
49 PV_NO_DUPLICATE | PV_NUMERIC))
53 /* Factor variable (s) */
54 while (lex_match (lexer, T_BY))
56 struct layer *layer = xzalloc (sizeof *layer);
57 hmap_init (&layer->instances.map);
60 table->layers = xrealloc (table->layers,
61 table->n_layers * sizeof *table->layers);
63 table->layers[table->n_layers - 1] = layer;
65 if (!parse_variables_const_pool
66 (lexer, cmd->pool, cmd->dict,
68 &layer->n_factor_vars,
77 If the match succeeds, the variable will be placed in VAR.
78 Returns true if successful */
80 lex_is_variable (struct lexer *lexer, const struct dictionary *dict,
84 if (lex_next_token (lexer, n) != T_ID)
87 tstr = lex_next_tokcstr (lexer, n);
89 if (NULL == dict_lookup_var (dict, tstr) )
96 means_parse (struct lexer *lexer, struct means *means)
98 /* Optional TABLES = */
99 if (lex_match_id (lexer, "TABLES"))
101 if (! lex_force_match (lexer, T_EQUALS))
105 bool more_tables = true;
106 /* Parse the "tables" */
110 means->table = pool_realloc (means->pool, means->table, means->n_tables * sizeof (*means->table));
112 if (! parse_means_table_syntax (lexer, means,
113 &means->table[means->n_tables - 1]))
118 /* Look ahead to see if there are more tables to be parsed */
120 if ( T_SLASH == lex_next_token (lexer, 0) )
122 if (lex_is_variable (lexer, means->dict, 1) )
125 lex_match (lexer, T_SLASH);
130 /* /MISSING subcommand */
131 while (lex_token (lexer) != T_ENDCMD)
133 lex_match (lexer, T_SLASH);
135 if (lex_match_id (lexer, "MISSING"))
138 If no MISSING subcommand is specified, each combination of
139 a dependent variable and categorical variables is handled
142 lex_match (lexer, T_EQUALS);
143 if (lex_match_id (lexer, "INCLUDE"))
146 Use the subcommand "/MISSING=INCLUDE" to include user-missing
147 values in the analysis.
150 means->exclude = MV_SYSTEM;
151 means->dep_exclude = MV_SYSTEM;
153 else if (lex_match_id (lexer, "TABLE"))
155 This is the default. (I think).
156 Every case containing a complete set of variables for a given
157 table. If any variable, categorical or dependent for in a table
158 is missing (as defined by what?), then that variable will
159 be dropped FOR THAT TABLE ONLY.
162 means->listwise_exclude = true;
164 else if (lex_match_id (lexer, "DEPENDENT"))
166 Use the command "/MISSING=DEPENDENT" to
167 include user-missing values for the categorical variables,
168 while excluding them for the dependent variables.
170 Cases are dropped only when user-missing values
171 appear in dependent variables. User-missing
172 values for categorical variables are treated according to
175 Cases are ALWAYS dropped when System Missing values appear
176 in the categorical variables.
179 means->dep_exclude = MV_ANY;
180 means->exclude = MV_SYSTEM;
184 lex_error (lexer, NULL);
188 else if (lex_match_id (lexer, "CELLS"))
190 lex_match (lexer, T_EQUALS);
192 /* The default values become overwritten */
193 means->n_statistics = 0;
194 free (means->statistics);
195 means->statistics = 0;
196 while (lex_token (lexer) != T_ENDCMD
197 && lex_token (lexer) != T_SLASH)
199 if (lex_match (lexer, T_ALL))
201 free (means->statistics);
202 means->statistics = xcalloc (n_MEANS_STATISTICS, sizeof (*means->statistics));
203 means->n_statistics = n_MEANS_STATISTICS;
205 for (i = 0; i < n_MEANS_STATISTICS; ++i)
207 means->statistics[i] = i;
210 else if (lex_match_id (lexer, "NONE"))
212 means->n_statistics = 0;
213 free (means->statistics);
214 means->statistics = 0;
216 else if (lex_match_id (lexer, "DEFAULT"))
218 means->n_statistics = 3;
219 means->statistics = xcalloc (3, sizeof *means->statistics);
220 means->statistics[0] = MEANS_MEAN;
221 means->statistics[1] = MEANS_N;
222 means->statistics[2] = MEANS_STDDEV;
227 for (i = 0; i < n_MEANS_STATISTICS; ++i)
229 const struct cell_spec *cs = cell_spec + i;
230 if (lex_match_id (lexer, cs->keyword))
233 = xrealloc (means->statistics,
234 (means->n_statistics + 1)
235 * sizeof (*means->statistics));
237 means->statistics[means->n_statistics] = i;
238 means->n_statistics++;
243 if (i >= n_MEANS_STATISTICS)
245 lex_error (lexer, NULL);
253 lex_error (lexer, NULL);
261 cmd_means (struct lexer *lexer, struct dataset *ds)
264 means.pool = pool_create ();
266 means.exclude = MV_ANY;
267 means.dep_exclude = MV_ANY;
268 means.listwise_exclude = false;
272 means.dict = dataset_dict (ds);
274 means.n_statistics = 3;
275 means.statistics = xcalloc (3, sizeof *means.statistics);
276 means.statistics[0] = MEANS_MEAN;
277 means.statistics[1] = MEANS_N;
278 means.statistics[2] = MEANS_STDDEV;
280 if (! means_parse (lexer, &means))
284 struct casegrouper *grouper;
285 struct casereader *group;
288 grouper = casegrouper_create_splits (proc_open (ds), means.dict);
289 while (casegrouper_get_next_group (grouper, &group))
291 run_means (&means, group, ds);
293 ok = casegrouper_destroy (grouper);
294 ok = proc_commit (ds) && ok;
297 for (int t = 0; t < means.n_tables; ++t)
299 const struct mtable *table = means.table + t;
300 means_shipout (table, &means);