X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fdata-io%2Fpivot.c;fp=src%2Flanguage%2Fdata-io%2Fpivot.c;h=22d7d1b2a60cb16b604a71bd0188275b5647d1cd;hb=bd0fbcb4295cf0fbcfa5c2a8fc607842c958ad65;hp=0000000000000000000000000000000000000000;hpb=2f5ea6bbd8c8c8a01f87bf3cdb9e1e1eab6e7fd6;p=pspp diff --git a/src/language/data-io/pivot.c b/src/language/data-io/pivot.c new file mode 100644 index 0000000000..22d7d1b2a6 --- /dev/null +++ b/src/language/data-io/pivot.c @@ -0,0 +1,189 @@ +/* PSPP - a program for statistical analysis. + Copyright (C) 2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +#include "data/casereader.h" +#include "data/dataset.h" +#include "data/subcase.h" +#include "language/command.h" +#include "language/lexer/lexer.h" +#include "language/lexer/variable-parser.h" +#include "math/sort.h" +#include "output/tab.h" +#include "output/table-item.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) + +enum + { + ROW_VAR, + COL_VAR, + DATA_VAR + }; + +struct cmd_pivot + { + const struct variable **vars[3]; + size_t n_vars[3]; + }; + +struct ccase * +take_first_case (struct ccase *first, struct ccase *second, void *aux UNUSED) +{ + case_unref (second); + return first; +} + +int +cmd_debug_pivot (struct lexer *lexer, struct dataset *ds) +{ + const struct dictionary *dict = dataset_dict (ds); + struct cmd_pivot p; + struct casereader *reader; + struct subcase col_ordering, total_ordering, row_ordering; + struct casereader *columns, *cells, *columns_reader; + struct ccase *row, *prev, *column; + int col_idx; + + memset (&p, 0, sizeof p); + while (lex_token (lexer) != T_ENDCMD) + { + lex_match (lexer, T_SLASH); + if (lex_match_id (lexer, "ROWS") ) + { + lex_match (lexer, T_EQUALS); + if (!parse_variables_const (lexer, dict, + &p.vars[ROW_VAR], &p.n_vars[ROW_VAR], + PV_NO_DUPLICATE | PV_NO_SCRATCH)) + return CMD_FAILURE; + } + else if (lex_match_id (lexer, "COLUMNS") ) + { + lex_match (lexer, T_EQUALS); + if (!parse_variables_const (lexer, dict, + &p.vars[COL_VAR], &p.n_vars[COL_VAR], + PV_NO_DUPLICATE | PV_NO_SCRATCH)) + return CMD_FAILURE; + } + else if (lex_match_id (lexer, "DATA") ) + { + lex_match (lexer, T_EQUALS); + if (!parse_variables_const (lexer, dict, + &p.vars[DATA_VAR], &p.n_vars[DATA_VAR], + PV_NO_DUPLICATE | PV_NO_SCRATCH)) + return CMD_FAILURE; + } + } + + + reader = proc_open (ds); + + subcase_init_vars (&col_ordering, p.vars[COL_VAR], p.n_vars[COL_VAR]); + columns = sort_distinct_execute (casereader_clone (reader), &col_ordering, + take_first_case, NULL, NULL); + printf ("%lld column combinations\n", + (long long int) casereader_count_cases (columns)); + + subcase_init_vars (&total_ordering, p.vars[ROW_VAR], p.n_vars[ROW_VAR]); + subcase_add_vars_always (&total_ordering, + p.vars[COL_VAR], p.n_vars[COL_VAR]); + cells = sort_distinct_execute (reader, &total_ordering, + take_first_case, NULL, NULL); + printf ("%lld cells\n", + (long long int) casereader_count_cases (cells)); + + row = prev = column = NULL; + columns_reader = NULL; + subcase_init_vars (&row_ordering, p.vars[ROW_VAR], p.n_vars[ROW_VAR]); + for (;;) + { + struct ccase *c; + + c = casereader_read (cells); + if (!c) + break; + + if (!row || !subcase_equal (&row_ordering, row, &row_ordering, c)) + { + int i; + + if (row) + putchar ('\n'); + case_unref (prev); + prev = row; + row = case_ref (c); + + i = 0; + if (prev) + for (; i < p.n_vars[ROW_VAR]; i++) + { + if (!value_equal (case_data (row, p.vars[ROW_VAR][i]), + case_data (prev, p.vars[ROW_VAR][i]), + var_get_width (p.vars[ROW_VAR][i]))) + break; + printf (" "); + } + for (; i < p.n_vars[ROW_VAR]; i++) + { + union value value; + const char *label; + + value.f = case_num (row, p.vars[ROW_VAR][i]); + label = var_lookup_value_label (p.vars[ROW_VAR][i], &value); + if (label) + printf ("%7s ", label); + else + printf ("%7.0f ", value.f); + } + printf ("| "); + + case_unref (column); + casereader_destroy (columns_reader); + columns_reader = casereader_clone (columns); + column = casereader_read (columns_reader); + col_idx = 0; + } + + while (!subcase_equal (&col_ordering, column, &col_ordering, c)) + { + case_unref (column); + column = casereader_read (columns_reader); + printf (" "); + col_idx++; + } + + printf ("%7.0f ", case_num (c, p.vars[DATA_VAR][0])); + col_idx++; + column = casereader_read (columns_reader); + } + if (row) + putchar ('\n'); + case_unref (row); + case_unref (prev); + case_unref (column); + casereader_destroy (columns_reader); + + casereader_destroy (columns); + casereader_destroy (cells); + subcase_destroy (&col_ordering); + subcase_destroy (&row_ordering); + + proc_commit (ds); + + return CMD_SUCCESS; +}