AUTORECODE: Implement PRINT subcommand.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 5 Oct 2019 03:18:18 +0000 (03:18 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 5 Oct 2019 03:18:18 +0000 (03:18 +0000)
NEWS
src/language/stats/autorecode.c
tests/language/stats/autorecode.at

diff --git a/NEWS b/NEWS
index 7df1da7248c41025fb70b5bbc7489d35ea7640d2..2c07d2a4161e4383d73b95accb5bdaed3d103938 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,12 @@ Changes from 1.2.0 to 1.3.0:
    sub-category as a percentage of the primary category instead of the
    total.
 
+ * AUTORECODE:
+
+   - The PRINT subcommand is now implemented.
+
+   - Many bug fixes.
+
 Changes from 1.0.1 to 1.2.0:
 
  * New experimental command SAVE DATA COLLECTION to save MDD files.
index d5a3ea970e9f5e6b4fb2cb6684705eacaa25bafe..dcd0a14d76fc1a0330774032cf35b3d3aaab8226 100644 (file)
@@ -36,6 +36,7 @@
 #include "libpspp/message.h"
 #include "libpspp/pool.h"
 #include "libpspp/str.h"
+#include "output/pivot-table.h"
 
 #include "gl/xalloc.h"
 #include "gl/c-xvasprintf.h"
@@ -44,8 +45,7 @@
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
-
-/* FIXME: Implement PRINT subcommand. */
+#define N_(msgid) (msgid)
 
 /* Explains how to recode one value. */
 struct arc_item
@@ -64,6 +64,8 @@ struct arc_spec
   {
     int width;                  /* Variable width. */
     int src_idx;                /* Case index of source variable. */
+    char *src_name;             /* Name of source variable. */
+    struct fmt_spec format;     /* Print format in source variable. */
     struct variable *dst;       /* Target variable. */
     struct missing_values mv;   /* Missing values of source variable. */
     char *label;                /* Variable label of source variable. */
@@ -126,6 +128,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
   size_t n_dsts = 0;
 
   enum arc_direction direction = ASCENDING;
+  bool print = false;
 
   /* Create procedure. */
   struct autorecode_pgm *arc = xzalloc (sizeof *arc);
@@ -171,9 +174,7 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
       if (lex_match_id (lexer, "DESCENDING"))
         direction = DESCENDING;
       else if (lex_match_id (lexer, "PRINT"))
-        {
-          /* Not yet implemented. */
-        }
+        print = true;
       else if (lex_match_id (lexer, "GROUP"))
         group = true;
       else if (lex_match_id (lexer, "BLANK"))
@@ -240,6 +241,8 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
 
       spec->width = var_get_width (src_vars[i]);
       spec->src_idx = var_get_case_index (src_vars[i]);
+      spec->src_name = xstrdup (var_get_name (src_vars[i]));
+      spec->format = *var_get_print_format (src_vars[i]);
 
       const char *label = var_get_label (src_vars[i]);
       spec->label = label ? xstrdup (label) : NULL;
@@ -353,6 +356,51 @@ cmd_autorecode (struct lexer *lexer, struct dataset *ds)
       for (j = 0; j < n_items; j++)
         items[j]->to = j + 1;
 
+      if (print && (!group || i == 0))
+        {
+          struct pivot_value *title
+            = (group
+               ? pivot_value_new_text (N_("Recoding grouped variables."))
+               : spec->label && spec->label[0]
+               ? pivot_value_new_text_format (N_("Recoding %s into %s (%s)."),
+                                              spec->src_name,
+                                              var_get_name (spec->dst),
+                                              spec->label)
+               : pivot_value_new_text_format (N_("Recoding %s into %s."),
+                                              spec->src_name,
+                                              var_get_name (spec->dst)));
+          struct pivot_table *table = pivot_table_create__ (title);
+
+          pivot_dimension_create (
+            table, PIVOT_AXIS_COLUMN, N_("Attributes"),
+            N_("New Value"), N_("Value Label"));
+
+          struct pivot_dimension *old_values = pivot_dimension_create (
+            table, PIVOT_AXIS_ROW, N_("Old Value"));
+          old_values->root->show_label = true;
+
+          for (size_t k = 0; k < n_items; k++)
+            {
+              const struct arc_item *item = items[k];
+              int old_value_idx = pivot_category_create_leaf (
+                old_values->root, pivot_value_new_value (
+                  &item->from, item->width,
+                  (item->width
+                   ? &(struct fmt_spec) { FMT_F, item->width, 0 }
+                   : &spec->format),
+                  dict_get_encoding (dict)));
+              pivot_table_put2 (table, 0, old_value_idx,
+                                pivot_value_new_integer (item->to));
+
+              const char *value_label = item->value_label;
+              if (value_label && value_label[0])
+                pivot_table_put2 (table, 1, old_value_idx,
+                                  pivot_value_new_user_text (value_label, -1));
+            }
+
+          pivot_table_submit (table);
+        }
+
       /* Assign user-missing values.
 
          User-missing values in the source variable(s) must be marked
@@ -438,6 +486,7 @@ arc_free (struct autorecode_pgm *arc)
               free (item);
             }
           free (spec->label);
+          free (spec->src_name);
           mv_destroy (&spec->mv);
         }
 
index 2077d562f6bc018c6889ed4109a8a3f5b4058078..2267a80a90497be84540f66dd0314b9d627d178f 100644 (file)
@@ -35,11 +35,65 @@ MISSING VALUES u (11)
               y (11 THRU 15)
               z (11 THRU 16).
 
-AUTORECODE u v w x y z INTO a b c d e f.
+AUTORECODE u v w x y z INTO a b c d e f/print.
 LIST.
 DISPLAY VARIABLES/VARIABLES=a TO f.
 ])
 AT_CHECK([pspp -O format=csv autorecode.sps], [0], [dnl
+Table: Recoding u into a.
+Old Value,New Value,Value Label
+12,1,12
+13,2,13
+14,3,14
+15,4,15
+16,5,16
+11,6,11
+
+Table: Recoding v into b.
+Old Value,New Value,Value Label
+13,1,13
+14,2,14
+15,3,15
+16,4,16
+11,5,11
+12,6,12
+
+Table: Recoding w into c.
+Old Value,New Value,Value Label
+14,1,14
+15,2,15
+16,3,16
+11,4,11
+12,5,12
+13,6,13
+
+Table: Recoding x into d.
+Old Value,New Value,Value Label
+15,1,15
+16,2,16
+11,3,11
+12,4,12
+13,5,13
+14,6,14
+
+Table: Recoding y into e.
+Old Value,New Value,Value Label
+16,1,16
+11,2,11
+12,3,12
+13,4,13
+14,5,14
+15,6,15
+
+Table: Recoding z into f.
+Old Value,New Value,Value Label
+11,1,11
+12,2,12
+13,3,13
+14,4,14
+15,5,15
+16,6,16
+
 Table: Data List
 u,v,w,x,y,z,a,b,c,d,e,f
 11,11,11,11,11,11,6,5,4,3,2,1
@@ -77,7 +131,7 @@ end data.
 
 missing values x('asdfk') y(9).
 
-autorecode x y into A B/descend.
+autorecode x y into A B/descend/print.
 
 list.
 compute Z=trunc(y/2).
@@ -91,6 +145,20 @@ Variable,Record,Columns,Format
 X,1,1-  5,A5
 Y,1,7-  7,F1.0
 
+Table: Recoding X into A.
+Old Value,New Value,Value Label
+lasdj,1,lasdj
+lajks,2,lajks
+asdfj,3,asdfj
+asdfk,4,asdfk
+
+Table: Recoding Y into B.
+Old Value,New Value,Value Label
+2,1,2
+1,2,1
+0,3,0
+9,4,9
+
 Table: Data List
 X,Y,A,B
 lasdj,1,1,2
@@ -117,8 +185,6 @@ asdfk,1,4,2,0,1
 ])
 AT_CLEANUP
 
-
-
 AT_SETUP([AUTORECODE long strings and check the value labels])
 AT_DATA([ar.sps],
   [data list notable list /s (a16) x (f1.0).
@@ -135,7 +201,7 @@ end data.
 variable labels s 'tracking my stuff'.
 value labels /s 'thingummies' 'Funny sticky things'.
 
-autorecode s into new.
+autorecode s into new/print.
 
 list.
 
@@ -143,7 +209,14 @@ display dictionary/variables=new.
 ])
 
 AT_CHECK([pspp -O format=csv ar.sps], [0],
-  [Table: Data List
+  [Table: Recoding s into new (tracking my stuff).
+Old Value,New Value,Value Label
+oojars,1,oojars
+oojimiflips,2,oojimiflips
+thingummies,3,Funny sticky things
+widgets,4,widgets
+
+Table: Data List
 s,x,new
 widgets,1,4
 thingummies,2,3
@@ -184,14 +257,26 @@ missing values y (12).
 
 autorecode 
        x y into a b
-       /group.
+       /group
+       /print.
 
 list.
 display variables /variables=a b.
 ])
 
 AT_CHECK([pspp -O format=csv ar-group.sps], [0],
-[Table: Data List
+[Table: Recoding grouped variables.
+Old Value,New Value,Value Label
+10,1,10
+11,2,11
+13,3,13
+14,4,14
+15,5,15
+16,6,16
+18,7,18
+12,8,12
+
+Table: Data List
 x,y,a,b
 11,10,2,1
 12,12,8,8
@@ -223,7 +308,8 @@ end data.
 
 
 autorecode x y into a b
-       /group.
+       /group
+       /print.
 
 delete variables x y.
 
@@ -232,7 +318,18 @@ list.
 ])
 
 AT_CHECK([pspp -O format=csv strings.sps], [0],
-[Table: Data List
+[Table: Recoding grouped variables.
+Old Value,New Value,Value Label
+,1,
+bert,2,bert
+charlie,3,charlie
+delta,4,delta
+echo,5,echo
+fred,6,fred
+nothing,7,nothing
+windows,8,windows
+
+Table: Data List
 a,b
 6,2
 3,1
@@ -257,13 +354,24 @@ four   nought
 end data.
 
 autorecode a b into x y 
-       /group.
+       /group
+       /print.
 
 list.
 ])
 
-AT_CHECK([pspp -O format=csv ar-strings.sps], [0],
-[dnl
+AT_CHECK([pspp -O format=csv ar-strings.sps], [0], [dnl
+Table: Recoding grouped variables.
+Old Value,New Value,Value Label
+eleven,1,eleven
+four,2,four
+nine,3,nine
+nought,4,nought
+one,5,one
+ten,6,ten
+three,7,three
+two,8,two
+
 Table: Data List
 a,b,x,y
 one,nine,5,3
@@ -288,12 +396,28 @@ two   4  ""
 three 2  charliebrown
 end data.
 
-autorecode variables x y z into a b c  /blank=missing.
+autorecode variables x y z into a b c  /blank=missing /print.
 
 list a b c y.
 ])
 
 AT_CHECK([pspp -O format=csv auto-blank.sps], [0], [dnl
+Table: Recoding x into a.
+Old Value,New Value,Value Label
+one,1,one
+three,2,three
+two,3,two
+
+Table: Recoding y into b.
+Old Value,New Value,Value Label
+2,1,2
+4,2,4
+
+Table: Recoding z into c.
+Old Value,New Value,Value Label
+charliebrown,1,charliebrown
+fred,2,fred
+
 Table: Data List
 a,b,c,y
 1,1,2,2
@@ -324,15 +448,26 @@ end data.
 
 temporary.
 select if y > 1.
-autorecode x y into A B/descend.
+autorecode x y into A B/descend/print.
 list.
 ])
-AT_CHECK([pspp -O format=csv autorecode.sps], [0],
-  [Table: Reading 1 record from INLINE.
+AT_CHECK([pspp -O format=csv autorecode.sps], [0], [dnl
+Table: Reading 1 record from INLINE.
 Variable,Record,Columns,Format
 X,1,1-  5,A5
 Y,1,7-  7,F1.0
 
+Table: Recoding X into A.
+Old Value,New Value,Value Label
+lajks,1,lajks
+asdfk,2,asdfk
+asdfj,3,asdfj
+
+Table: Recoding Y into B.
+Old Value,New Value,Value Label
+9,1,9
+2,2,2
+
 Table: Data List
 X,Y,A,B
 lasdj,1,.,.
@@ -363,12 +498,20 @@ begin data.
 8
 end data.
 
-autorecode x  /into y.
+autorecode x  /into y /print.
 
 list.
 ])
 AT_CHECK([pspp -O format=csv autorecode.sps], [0],
-[Table: Data List
+[Table: Recoding x into y.
+Old Value,New Value,Value Label
+-901,1,-901
+1,2,1
+4,3,4
+8,4,8
+99,5,99
+
+Table: Data List
 x,y
 1,2
 8,4