From 899e0af5a1de32d108cb27fdca2c8c105f5bdd45 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sat, 5 Oct 2019 03:18:18 +0000 Subject: [PATCH] AUTORECODE: Implement PRINT subcommand. --- NEWS | 6 + src/language/stats/autorecode.c | 59 +++++++++- tests/language/stats/autorecode.at | 181 ++++++++++++++++++++++++++--- 3 files changed, 222 insertions(+), 24 deletions(-) diff --git a/NEWS b/NEWS index 7df1da7248..2c07d2a416 100644 --- 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. diff --git a/src/language/stats/autorecode.c b/src/language/stats/autorecode.c index d5a3ea970e..dcd0a14d76 100644 --- a/src/language/stats/autorecode.c +++ b/src/language/stats/autorecode.c @@ -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); } diff --git a/tests/language/stats/autorecode.at b/tests/language/stats/autorecode.at index 2077d562f6..2267a80a90 100644 --- a/tests/language/stats/autorecode.at +++ b/tests/language/stats/autorecode.at @@ -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 -- 2.30.2