work on pivot table and FREQUENCIES usage
[pspp] / src / output / pivot-table.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2010 Free Software Foundation, Inc.
3
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.
8
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.
13
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/>. */
16
17 #include <config.h>
18
19 #include "output/pivot-table.h"
20
21 #include "data/case.h"
22 #include "data/casereader.h"
23 #include "math/sort.h"
24
25 #include "gl/xalloc.h"
26
27 void
28 pivot_cell_init (struct pivot_cell *cell, struct pivot_value *value)
29 {
30   cell->base = value;
31   cell->cmp = PIVOT_RAW;
32   cell->cmp_args[0] = cell->cmp_args[1] = cell->cmp_args[2] = NULL;
33   cell->label = NULL;
34   cell->format = F_8_0;
35 }
36
37 struct pivot_value *
38 pivot_value_create (const struct variable *var,
39                     enum pivot_operator operator,
40                     int n_vars_horz,
41                     int n_vars_vert,
42                     enum pivot_value_include include)
43 {
44   struct pivot_value *value = xmalloc (sizeof *value);
45   value->var = var;
46   value->operator = operator;
47   value->n_agg_vars[TABLE_HORZ] = n_vars_horz;
48   value->n_agg_vars[TABLE_VERT] = n_vars_vert;
49   value->include = include;
50   return value;
51 }
52
53 static struct ccase *
54 keep_one (struct ccase *a, struct ccase *b, void *aux UNUSED)
55 {
56   case_unref (b);
57   return a;
58 }
59
60 static void
61 dump_projection (struct casereader *data, const struct subcase *split,
62                  const struct subcase *vars)
63 {
64   struct subcase sc;
65   struct ccase *c;
66
67   subcase_clone (&sc, split);
68   subcase_concat_always (&sc, vars);
69
70   data = casereader_project (data, &sc);
71   data = sort_distinct_execute (data, &sc, keep_one, NULL, NULL);
72
73 #if 0
74   for (; (c = casereader_read (data)) != NULL; case_unref (c))
75     {
76       const struct caseproto *proto = case_get_proto (c);
77       size_t i;
78
79       for (i = 0; i < caseproto_get_n_widths (proto); i++)
80         {
81           int width = caseproto_get_width (proto, i);
82
83           if (i > 0)
84             putchar (' ');
85
86           if (width == 0)
87             printf ("%8.2g", case_num_idx (c, i));
88           else
89             printf ("\"%.*s\"", width, case_str_idx (c, i));
90         }
91       printf ("\n");
92     }
93 #endif
94
95   subcase_destroy (&sc);
96 }
97
98 static void
99 dump_data (struct pivot_table *pt)
100 {
101   struct casereader *data;
102   struct subcase sc;
103   struct ccase *c;
104
105   subcase_clone (&sc, &pt->split);
106   subcase_concat_always (&sc, &pt->dimensions[TABLE_HORZ]);
107   subcase_concat_always (&sc, &pt->dimensions[TABLE_VERT]);
108
109   data = sort_distinct_execute (casereader_clone (pt->data), &sc, keep_one, NULL, NULL);
110   for (; (c = casereader_read (data)) != NULL; case_unref (c))
111     {
112       const struct caseproto *proto = case_get_proto (c);
113       size_t i;
114
115       for (i = 0; i < caseproto_get_n_widths (proto); i++)
116         {
117           int width = caseproto_get_width (proto, i);
118
119           if (i > 0)
120             putchar (' ');
121
122           if (width == 0)
123             printf ("%8.2f", case_num_idx (c, i));
124           else
125             printf ("\"%.*s\"", width, case_str_idx (c, i));
126         }
127       printf ("\n");
128     }
129
130 }
131
132 void
133 pivot_table_dump (struct pivot_table *pt)
134 {
135   /* Strategy:
136
137      Determine row and column labels:
138
139        Project onto (splits, rows) and sort, discarding duplicates.
140
141        Project onto (splits, columns) and sort, discarding duplicates.
142
143      Sort data on (splits, rows, columns).
144
145      For each split group:
146
147        For each row value:
148
149          For each column value:
150
151            For each value in the pane:
152
153              Evaluate and print value.
154
155   */
156
157   dump_projection (casereader_clone (pt->data),
158                    &pt->split, &pt->dimensions[TABLE_HORZ]);
159   dump_projection (casereader_clone (pt->data),
160                    &pt->split, &pt->dimensions[TABLE_VERT]);
161
162   dump_data (pt);
163   
164
165   casereader_destroy (pt->data);
166 }