2-d subtotals work
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 29 Jan 2022 02:30:20 +0000 (18:30 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Sun, 13 Mar 2022 23:56:02 +0000 (16:56 -0700)
src/language/stats/ctables.c
tests/language/stats/ctables.at

index b57f33f5d7ef4a35203433e231d49057820fffb9..c982f19cf63ad431faaf532c0637133daf43b574 100644 (file)
@@ -2447,6 +2447,34 @@ recurse_totals (struct ctables_table *t, const struct ccase *c,
     }
 }
 
+static void
+recurse_subtotals (struct ctables_table *t, const struct ccase *c,
+                   size_t ix[PIVOT_N_AXES],
+                   const struct ctables_category *cats[PIVOT_N_AXES][10],
+                   double weight,
+                   enum pivot_axis_type start_axis, size_t start_nest)
+{
+  for (enum pivot_axis_type a = start_axis; a < PIVOT_N_AXES; a++)
+    {
+      const struct ctables_nest *nest = &t->stacks[a].nests[ix[a]];
+      for (size_t i = start_nest; i < nest->n; i++)
+        {
+          if (i == nest->scale_idx)
+            continue;
+
+          const struct ctables_category *save = cats[a][i];
+          if (save->subtotal)
+            {
+              cats[a][i] = save->subtotal;
+              ctables_cell_add__ (t, c, ix, cats, weight);
+              recurse_subtotals (t, c, ix, cats, weight, a, i + 1);
+              cats[a][i] = save;
+            }
+        }
+      start_nest = 0;
+    }
+}
+
 static void
 ctables_cell_insert (struct ctables_table *t,
                      const struct ccase *c,
@@ -2484,24 +2512,7 @@ ctables_cell_insert (struct ctables_table *t,
   ctables_cell_add__ (t, c, ix, cats, weight);
 
   recurse_totals (t, c, ix, cats, weight, 0, 0);
-
-  for (enum pivot_axis_type a = 0; a < PIVOT_N_AXES; a++)
-    {
-      const struct ctables_nest *nest = &t->stacks[a].nests[ix[a]];
-      for (size_t i = 0; i < nest->n; i++)
-        {
-          if (i == nest->scale_idx)
-            continue;
-
-          const struct ctables_category *save = cats[a][i];
-          if (save->subtotal)
-            {
-              cats[a][i] = save->subtotal;
-              ctables_cell_add__ (t, c, ix, cats, weight);
-              cats[a][i] = save;
-            }
-        }
-    }
+  recurse_subtotals (t, c, ix, cats, weight, 0, 0);
 }
 
 struct merge_item
index 46147b42c064400a5690434cc87dfc39370e1709..511ea02d1831a44f822cfa1e2cb5d3981dd29468 100644 (file)
@@ -479,7 +479,6 @@ AT_CHECK([pspp ctables.sps -O box=unicode -O width=80], [0], [dnl
 ])
 AT_CLEANUP
 
-
 AT_SETUP([CTABLES simple totals])
 AT_CHECK([ln $top_srcdir/examples/nhtsa.sav . || cp $top_srcdir/examples/nhtsa.sav .])
 AT_DATA([ctables.sps],
@@ -532,3 +531,82 @@ AT_CHECK([pspp ctables.sps -O box=unicode -O width=80], [0], [dnl
 ╰───────────────────────────────────────────────────────────────────┴────┴─────╯
 ])
 AT_CLEANUP
+
+AT_SETUP([CTABLES subtotals])
+AT_CHECK([ln $top_srcdir/examples/nhtsa.sav . || cp $top_srcdir/examples/nhtsa.sav .])
+AT_DATA([ctables.sps],
+[[GET 'nhtsa.sav'.
+CTABLES /TABLE=qn105ba BY qns1
+    /CATEGORIES VARIABLES=qns1 [1, 2, SUBTOTAL, 3, 4, 5, SUBTOTAL].
+CTABLES /TABLE=qn105ba [COLPCT] BY qns1
+    /CATEGORIES VARIABLES=qn105ba [1, 2, 3, SUBTOTAL, 4, 5, SUBTOTAL].
+CTABLES /TABLE=qn105ba BY qns1
+    /CATEGORIES VARIABLES=qn105ba [1, 2, 3, SUBTOTAL, 4, 5, SUBTOTAL]
+    /CATEGORIES VARIABLES=qns1 [1, 2, SUBTOTAL, 3, 4, 5, SUBTOTAL].
+]])
+AT_CHECK([pspp ctables.sps -O box=unicode -O width=120], [0], [dnl
+                                                      Custom Tables
+╭─────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────╮
+│                                                         │ S1. Including yourself, how many members of this household │
+│                                                         │                    are age 16 or older?                    │
+│                                                         ├───────┬───────┬─────────┬───────┬────────┬──────┬──────────┤
+│                                                         │   1   │   2   │ Subtotal│   3   │    4   │   5  │ Subtotal │
+│                                                         ├───────┼───────┼─────────┼───────┼────────┼──────┼──────────┤
+│                                                         │ Count │ Count │  Count  │ Count │  Count │ Count│   Count  │
+├─────────────────────────────────────────────────────────┼───────┼───────┼─────────┼───────┼────────┼──────┼──────────┤
+│105b. How likely is it that drivers who have  Almost     │    147│    246│      393│     62│      19│    11│        92│
+│had too much to drink to drive safely will A. certain    │       │       │         │       │        │      │          │
+│Get stopped by the police?                    Very likely│    384│    552│      936│    120│      51│    14│       185│
+│                                              Somewhat   │    590│   1249│     1839│    193│      72│    20│       285│
+│                                              likely     │       │       │         │       │        │      │          │
+│                                              Somewhat   │    278│    647│      925│     84│      32│     6│       122│
+│                                              unlikely   │       │       │         │       │        │      │          │
+│                                              Very       │    141│    290│      431│     41│      18│     4│        63│
+│                                              unlikely   │       │       │         │       │        │      │          │
+╰─────────────────────────────────────────────────────────┴───────┴───────┴─────────┴───────┴────────┴──────┴──────────╯
+
+                                                      Custom Tables
+╭────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────╮
+│                                                            │     S1. Including yourself, how many members of this    │
+│                                                            │              household are age 16 or older?             │
+│                                                            ├─────────┬────────┬─────────┬────────┬─────────┬─────────┤
+│                                                            │    1    │    2   │    3    │    4   │    5    │6 or more│
+│                                                            ├─────────┼────────┼─────────┼────────┼─────────┼─────────┤
+│                                                            │ Column %│Column %│ Column %│Column %│ Column %│ Column %│
+├────────────────────────────────────────────────────────────┼─────────┼────────┼─────────┼────────┼─────────┼─────────┤
+│105b. How likely is it that drivers who have had Almost     │     4.8%│    4.1%│     6.2%│    4.9%│    10.0%│    11.9%│
+│too much to drink to drive safely will A. Get    certain    │         │        │         │        │         │         │
+│stopped by the police?                           Very likely│    12.5%│    9.2%│    12.0%│   13.3%│    12.7%│    16.7%│
+│                                                 Somewhat   │    19.2%│   20.9%│    19.3%│   18.8%│    18.2%│    11.9%│
+│                                                 likely     │         │        │         │        │         │         │
+│                                                 Subtotal   │    36.4%│   34.3%│    37.5%│   37.0%│    40.9%│    40.5%│
+│                                                 Somewhat   │     9.0%│   10.8%│     8.4%│    8.3%│     5.5%│     4.8%│
+│                                                 unlikely   │         │        │         │        │         │         │
+│                                                 Very       │     4.6%│    4.9%│     4.1%│    4.7%│     3.6%│     4.8%│
+│                                                 unlikely   │         │        │         │        │         │         │
+│                                                 Subtotal   │    13.6%│   15.7%│    12.5%│   13.0%│     9.1%│     9.5%│
+╰────────────────────────────────────────────────────────────┴─────────┴────────┴─────────┴────────┴─────────┴─────────╯
+
+                                                      Custom Tables
+╭─────────────────────────────────────────────────────────┬────────────────────────────────────────────────────────────╮
+│                                                         │ S1. Including yourself, how many members of this household │
+│                                                         │                    are age 16 or older?                    │
+│                                                         ├───────┬───────┬─────────┬───────┬────────┬──────┬──────────┤
+│                                                         │   1   │   2   │ Subtotal│   3   │    4   │   5  │ Subtotal │
+│                                                         ├───────┼───────┼─────────┼───────┼────────┼──────┼──────────┤
+│                                                         │ Count │ Count │  Count  │ Count │  Count │ Count│   Count  │
+├─────────────────────────────────────────────────────────┼───────┼───────┼─────────┼───────┼────────┼──────┼──────────┤
+│105b. How likely is it that drivers who have  Almost     │    147│    246│      393│     62│      19│    11│        92│
+│had too much to drink to drive safely will A. certain    │       │       │         │       │        │      │          │
+│Get stopped by the police?                    Very likely│    384│    552│      936│    120│      51│    14│       185│
+│                                              Somewhat   │    590│   1249│     1839│    193│      72│    20│       285│
+│                                              likely     │       │       │         │       │        │      │          │
+│                                              Subtotal   │   1121│   2047│     3168│    375│     142│    45│       562│
+│                                              Somewhat   │    278│    647│      925│     84│      32│     6│       122│
+│                                              unlikely   │       │       │         │       │        │      │          │
+│                                              Very       │    141│    290│      431│     41│      18│     4│        63│
+│                                              unlikely   │       │       │         │       │        │      │          │
+│                                              Subtotal   │    419│    937│     1356│    125│      50│    10│       185│
+╰─────────────────────────────────────────────────────────┴───────┴───────┴─────────┴───────┴────────┴──────┴──────────╯
+])
+AT_CLEANUP