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,
43 memset (table, 0, sizeof *table);
45 /* Dependent variable (s) */
46 if (!parse_variables_const_pool (lexer, cmd->pool, cmd->dict,
47 &table->dep_vars, &table->n_dep_vars,
48 PV_NO_DUPLICATE | PV_NUMERIC))
51 /* Factor variable (s) */
52 while (lex_match (lexer, T_BY))
54 struct layer *layer = pool_zalloc (cmd->pool, sizeof *layer);
57 pool_nrealloc (cmd->pool, table->layers, table->n_layers + 1,
58 sizeof *table->layers);
59 table->layers[table->n_layers] = layer;
62 if (!parse_variables_const_pool
63 (lexer, cmd->pool, cmd->dict,
65 &layer->n_factor_vars,
74 If the match succeeds, the variable will be placed in VAR.
75 Returns true if successful */
77 lex_is_variable (struct lexer *lexer, const struct dictionary *dict,
81 if (lex_next_token (lexer, n) != T_ID)
84 tstr = lex_next_tokcstr (lexer, n);
86 if (NULL == dict_lookup_var (dict, tstr) )
93 means_parse (struct lexer *lexer, struct means *means)
95 /* Optional TABLES = */
96 if (lex_match_id (lexer, "TABLES"))
98 if (! lex_force_match (lexer, T_EQUALS))
102 bool more_tables = true;
103 /* Parse the "tables" */
106 means->table = pool_realloc (means->pool, means->table,
107 (means->n_tables + 1) * sizeof (*means->table));
109 if (! parse_means_table_syntax (lexer, means,
110 &means->table[means->n_tables]))
116 /* Look ahead to see if there are more tables to be parsed */
118 if ( T_SLASH == lex_next_token (lexer, 0) )
120 if (lex_is_variable (lexer, means->dict, 1) )
123 lex_match (lexer, T_SLASH);
128 /* /MISSING subcommand */
129 while (lex_token (lexer) != T_ENDCMD)
131 lex_match (lexer, T_SLASH);
133 if (lex_match_id (lexer, "MISSING"))
136 If no MISSING subcommand is specified, each combination of
137 a dependent variable and categorical variables is handled
140 lex_match (lexer, T_EQUALS);
141 if (lex_match_id (lexer, "INCLUDE"))
144 Use the subcommand "/MISSING=INCLUDE" to include user-missing
145 values in the analysis.
148 means->ctrl_exclude = MV_SYSTEM;
149 means->dep_exclude = MV_SYSTEM;
151 else if (lex_match_id (lexer, "DEPENDENT"))
153 Use the command "/MISSING=DEPENDENT" to
154 include user-missing values for the categorical variables,
155 while excluding them for the dependent variables.
157 Cases are dropped only when user-missing values
158 appear in dependent variables. User-missing
159 values for categorical variables are treated according to
162 Cases are ALWAYS dropped when System Missing values appear
163 in the categorical variables.
166 means->dep_exclude = MV_ANY;
167 means->ctrl_exclude = MV_SYSTEM;
171 lex_error (lexer, NULL);
175 else if (lex_match_id (lexer, "CELLS"))
177 lex_match (lexer, T_EQUALS);
179 /* The default values become overwritten */
180 means->n_statistics = 0;
181 pool_free (means->pool, means->statistics);
182 means->statistics = 0;
183 while (lex_token (lexer) != T_ENDCMD
184 && lex_token (lexer) != T_SLASH)
186 if (lex_match (lexer, T_ALL))
188 pool_free (means->pool, means->statistics);
189 means->statistics = pool_calloc (means->pool,
191 sizeof (*means->statistics));
192 means->n_statistics = n_MEANS_STATISTICS;
194 for (i = 0; i < n_MEANS_STATISTICS; ++i)
196 means->statistics[i] = i;
199 else if (lex_match_id (lexer, "NONE"))
201 means->n_statistics = 0;
202 pool_free (means->pool, means->statistics);
203 means->statistics = 0;
205 else if (lex_match_id (lexer, "DEFAULT"))
207 pool_free (means->pool, means->statistics);
208 means->statistics = pool_calloc (means->pool,
210 sizeof *means->statistics);
211 means->statistics[0] = MEANS_MEAN;
212 means->statistics[1] = MEANS_N;
213 means->statistics[2] = MEANS_STDDEV;
218 for (i = 0; i < n_MEANS_STATISTICS; ++i)
220 const struct cell_spec *cs = cell_spec + i;
221 if (lex_match_id (lexer, cs->keyword))
224 = pool_realloc (means->pool,
226 (means->n_statistics + 1)
227 * sizeof (*means->statistics));
229 means->statistics[means->n_statistics] = i;
230 means->n_statistics++;
235 if (i >= n_MEANS_STATISTICS)
237 lex_error (lexer, NULL);
245 lex_error (lexer, NULL);
254 cmd_means (struct lexer *lexer, struct dataset *ds)
257 means.pool = pool_create ();
259 means.ctrl_exclude = MV_ANY;
260 means.dep_exclude = MV_ANY;
264 means.dict = dataset_dict (ds);
266 means.n_statistics = 3;
267 means.statistics = pool_calloc (means.pool, 3, sizeof *means.statistics);
268 means.statistics[0] = MEANS_MEAN;
269 means.statistics[1] = MEANS_N;
270 means.statistics[2] = MEANS_STDDEV;
272 if (! means_parse (lexer, &means))
276 struct casegrouper *grouper;
277 struct casereader *group;
280 grouper = casegrouper_create_splits (proc_open (ds), means.dict);
281 while (casegrouper_get_next_group (grouper, &group))
283 run_means (&means, group, ds);
285 ok = casegrouper_destroy (grouper);
286 ok = proc_commit (ds) && ok;
289 for (int t = 0; t < means.n_tables; ++t)
291 const struct mtable *table = means.table + t;
293 means_case_processing_summary (table);
294 means_shipout (table, &means);
296 destroy_means (&means);
297 pool_destroy (means.pool);
302 destroy_means (&means);
303 pool_destroy (means.pool);