f12185a410492f826dfd8b67fdfbd15a6b909253
[pspp] / tests / language / xforms / recode.at
1 dnl PSPP - a program for statistical analysis.
2 dnl Copyright (C) 2017 Free Software Foundation, Inc.
3 dnl
4 dnl This program is free software: you can redistribute it and/or modify
5 dnl it under the terms of the GNU General Public License as published by
6 dnl the Free Software Foundation, either version 3 of the License, or
7 dnl (at your option) any later version.
8 dnl
9 dnl This program is distributed in the hope that it will be useful,
10 dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
11 dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 dnl GNU General Public License for more details.
13 dnl
14 dnl You should have received a copy of the GNU General Public License
15 dnl along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 dnl
17 AT_BANNER([RECODE transformation])
18
19 m4_define([RECODE_SAMPLE_DATA],
20   [DATA LIST LIST NOTABLE/x (f1) s (a4) t (a10).
21 MISSING VALUES x(9)/s('xxx').
22 BEGIN DATA.
23 0, '', ''
24 1, a, a
25 2, ab, ab
26 3, abc, abc
27 4, abcd, abcd
28 5, 123, 123
29 6, ' 123', ' 123'
30 7, +1, +1
31 8, 1x, 1x
32 9, abcd, abcdefghi
33 ,  xxx, abcdefghij
34 END DATA.
35 ])
36
37 AT_SETUP([RECODE numeric to numeric, without INTO])
38 AT_DATA([recode.sps],
39   [RECODE_SAMPLE_DATA
40 NUMERIC x0 TO x8 (F3).
41 MISSING VALUES x0 to x8 (9).
42 COMPUTE x0=value(x).
43 RECODE x0 (1=9).
44 COMPUTE x1=value(x).
45 RECODE x1 (1=9)(3=8)(5=7).
46 COMPUTE x2=value(x).
47 RECODE x2 (1=8)(2,3,4,5,6,8=9)(9=1).
48 COMPUTE x3=value(x).
49 RECODE x3 (1 THRU 9=10)(MISSING=11).
50 COMPUTE x4=value(x).
51 RECODE x4 (MISSING=11)(1 THRU 9=10).
52 COMPUTE x5=value(x).
53 RECODE x5 (LOWEST THRU 5=1).
54 COMPUTE x6=value(x).
55 RECODE x6 (4 THRU HIGHEST=2).
56 COMPUTE x7=value(x).
57 RECODE x7 (LO THRU HI=3).
58 COMPUTE x8=value(x).
59 RECODE x8 (SYSMIS=4).
60 LIST x x0 TO x8.
61 ])
62 AT_CHECK([pspp -O format=csv recode.sps], [0],
63   [Table: Data List
64 x,x0,x1,x2,x3,x4,x5,x6,x7,x8
65 0,0,0,0,0,0,1,0,3,0
66 1,9,9,8,10,10,1,1,3,1
67 2,2,2,9,10,10,1,2,3,2
68 3,3,8,9,10,10,1,3,3,3
69 4,4,4,9,10,10,1,2,3,4
70 5,5,7,9,10,10,1,2,3,5
71 6,6,6,9,10,10,6,2,3,6
72 7,7,7,7,10,10,7,2,3,7
73 8,8,8,9,10,10,8,2,3,8
74 9,9,9,1,10,11,9,2,3,9
75 .,.,.,.,11,11,.,.,.,4
76 ])
77 AT_CLEANUP
78
79 AT_SETUP([RECODE numeric to numeric, with INTO, without COPY])
80 AT_DATA([recode.sps],
81   [RECODE_SAMPLE_DATA
82 NUMERIC ix0 TO ix8 (F3).
83 RECODE x (1=9) INTO ix0.
84 RECODE x (1=9)(3=8)(5=7) INTO ix1.
85 RECODE x (1=8)(2,3,4,5,6,8=9)(9=1) INTO ix2.
86 RECODE x (1 THRU 9=10)(MISSING=11) INTO ix3.
87 RECODE x (MISSING=11)(1 THRU 9=10) INTO ix4.
88 RECODE x (LOWEST THRU 5=1) INTO ix5.
89 RECODE x (4 THRU HIGHEST=2) INTO ix6.
90 RECODE x (LO THRU HI=3) INTO ix7.
91 RECODE x (SYSMIS=4) INTO ix8.
92 LIST x ix0 TO ix8.
93 ])
94 AT_CHECK([pspp -O format=csv recode.sps], [0],
95   [Table: Data List
96 x,ix0,ix1,ix2,ix3,ix4,ix5,ix6,ix7,ix8
97 0,.,.,.,.,.,1,.,3,.
98 1,9,9,8,10,10,1,.,3,.
99 2,.,.,9,10,10,1,.,3,.
100 3,.,8,9,10,10,1,.,3,.
101 4,.,.,9,10,10,1,2,3,.
102 5,.,7,9,10,10,1,2,3,.
103 6,.,.,9,10,10,.,2,3,.
104 7,.,.,.,10,10,.,2,3,.
105 8,.,.,9,10,10,.,2,3,.
106 9,.,.,1,10,11,.,2,3,.
107 .,.,.,.,11,11,.,.,.,4
108 ])
109 AT_CLEANUP
110
111 AT_SETUP([RECODE numeric to numeric, with INTO, with COPY])
112 AT_DATA([recode.sps],
113   [RECODE_SAMPLE_DATA
114 NUMERIC cx0 TO cx8 (F3).
115 RECODE x (1=9)(ELSE=COPY) INTO cx0.
116 RECODE x (1=9)(3=8)(5=7)(ELSE=COPY) INTO cx1.
117 RECODE x (1=8)(2,3,4,5,6,8=9)(9=1)(ELSE=COPY) INTO cx2.
118 RECODE x (1 THRU 9=10)(MISSING=11)(ELSE=COPY) INTO cx3.
119 RECODE x (MISSING=11)(1 THRU 9=10)(ELSE=COPY) INTO cx4.
120 RECODE x (LOWEST THRU 5=1)(ELSE=COPY) INTO cx5.
121 RECODE x (4 THRU HIGHEST=2)(ELSE=COPY) INTO cx6.
122 RECODE x (LO THRU HI=3)(ELSE=COPY) INTO cx7.
123 RECODE x (SYSMIS=4)(ELSE=COPY) INTO cx8.
124 RECODE x (5=COPY)(ELSE=22) INTO cx9.
125 LIST x cx0 TO cx9.
126 ])
127 AT_CHECK([pspp -O format=csv recode.sps], [0],
128   [Table: Data List
129 x,cx0,cx1,cx2,cx3,cx4,cx5,cx6,cx7,cx8,cx9
130 0,0,0,0,0,0,1,0,3,0,22.00
131 1,9,9,8,10,10,1,1,3,1,22.00
132 2,2,2,9,10,10,1,2,3,2,22.00
133 3,3,8,9,10,10,1,3,3,3,22.00
134 4,4,4,9,10,10,1,2,3,4,22.00
135 5,5,7,9,10,10,1,2,3,5,5.00
136 6,6,6,9,10,10,6,2,3,6,22.00
137 7,7,7,7,10,10,7,2,3,7,22.00
138 8,8,8,9,10,10,8,2,3,8,22.00
139 9,9,9,1,10,11,9,2,3,9,22.00
140 .,.,.,.,11,11,.,.,.,4,22.00
141 ])
142 AT_CLEANUP
143
144 AT_SETUP([RECODE string to string, with INTO, without COPY])
145 AT_DATA([recode.sps],
146   [RECODE_SAMPLE_DATA
147 STRING s0 TO s3 (A4)/t0 TO t3 (A10).
148 RECODE s t ('a'='b')('ab'='bc') INTO s0 t0.
149 RECODE s t ('abcd'='xyzw') INTO s1 t1.
150 RECODE s t ('abc'='def')(ELSE='xyz') INTO s2 t2.
151 RECODE t ('a'='b')('abcdefghi'='xyz')('abcdefghij'='jklmnopqr') INTO t3.
152 RECODE s (MISSING='gone') INTO s3.
153 LIST s t s0 TO s3 t0 TO t3.
154 ])
155 AT_CHECK([pspp -O format=csv recode.sps], [0],
156   [Table: Data List
157 s,t,s0,s1,s2,s3,t0,t1,t2,t3
158 ,,,,xyz,,,,xyz,
159 a,a,b,,xyz,,b,,xyz,b
160 ab,ab,bc,,xyz,,bc,,xyz,
161 abc,abc,,,def,,,,def,
162 abcd,abcd,,xyzw,xyz,,,xyzw,xyz,
163 123,123,,,xyz,,,,xyz,
164 123,123,,,xyz,,,,xyz,
165 +1,+1,,,xyz,,,,xyz,
166 1x,1x,,,xyz,,,,xyz,
167 abcd,abcdefghi,,xyzw,xyz,,,,xyz,xyz
168 xxx,abcdefghij,,,xyz,gone,,,xyz,jklmnopqr
169 ])
170 AT_CLEANUP
171
172 AT_SETUP(RECODE string to string, with INTO, with COPY])
173 AT_DATA([recode.sps],
174   [RECODE_SAMPLE_DATA
175 STRING cs0 TO cs2 (A4)/ct0 TO ct3 (A10).
176 RECODE s t ('a'='b')('ab'='bc')(ELSE=COPY) INTO cs0 ct0.
177 RECODE s t ('abcd'='xyzw')(ELSE=COPY) INTO cs1 ct1.
178 RECODE s t ('abc'='def')(ELSE='xyz')(ELSE=COPY) INTO cs2 ct2.
179 RECODE t ('a'='b')('abcdefghi'='xyz')('abcdefghij'='jklmnopqr')(ELSE=COPY)
180     INTO ct3.
181 LIST s t cs0 TO cs2 ct0 TO ct3.
182 ])
183 AT_CHECK([pspp -O format=csv recode.sps], [0],
184   [Table: Data List
185 s,t,cs0,cs1,cs2,ct0,ct1,ct2,ct3
186 ,,,,xyz,,,xyz,
187 a,a,b,a,xyz,b,a,xyz,b
188 ab,ab,bc,ab,xyz,bc,ab,xyz,ab
189 abc,abc,abc,abc,def,abc,abc,def,abc
190 abcd,abcd,abcd,xyzw,xyz,abcd,xyzw,xyz,abcd
191 123,123,123,123,xyz,123,123,xyz,123
192 123,123,123,123,xyz,123,123,xyz,123
193 +1,+1,+1,+1,xyz,+1,+1,xyz,+1
194 1x,1x,1x,1x,xyz,1x,1x,xyz,1x
195 abcd,abcdefghi,abcd,xyzw,xyz,abcdefghi,abcdefghi,xyz,xyz
196 xxx,abcdefghij,xxx,xxx,xyz,abcdefghij,abcdefghij,xyz,jklmnopqr
197 ])
198 AT_CLEANUP
199
200 AT_SETUP([RECODE string to numeric])
201 AT_DATA([recode.sps],
202   [RECODE_SAMPLE_DATA
203 NUMERIC ns0 TO ns2 (F3)/nt0 TO nt2 (F3).
204 RECODE s t (CONVERT)(' '=0)('abcd'=1) INTO ns0 nt0.
205 RECODE s t (' '=0)(CONVERT)('abcd'=1) INTO ns1 nt1.
206 RECODE s t ('1x'=1)('abcd'=2)(ELSE=3) INTO ns2 nt2.
207 LIST s t ns0 TO ns2 nt0 TO nt2.
208 ])
209 AT_CHECK([pspp -O format=csv recode.sps], [0],
210   [Table: Data List
211 s,t,ns0,ns1,ns2,nt0,nt1,nt2
212 ,,.,0,3,.,0,3
213 a,a,.,.,3,.,.,3
214 ab,ab,.,.,3,.,.,3
215 abc,abc,.,.,3,.,.,3
216 abcd,abcd,1,1,2,1,1,2
217 123,123,123,123,3,123,123,3
218 123,123,123,123,3,123,123,3
219 +1,+1,1,1,3,1,1,3
220 1x,1x,.,.,1,.,.,1
221 abcd,abcdefghi,1,1,2,.,.,3
222 xxx,abcdefghij,.,.,3,.,.,3
223 ])
224 AT_CLEANUP
225
226 AT_SETUP([RECODE numeric to string])
227 AT_DATA([recode.sps],
228   [RECODE_SAMPLE_DATA
229 STRING sx0 TO sx2 (a10).
230 RECODE x (1 THRU 9='abcdefghij') INTO sx0.
231 RECODE x (0,1,3,5,7,MISSING='xxx') INTO sx1.
232 RECODE x (2 THRU 6,SYSMIS='xyz')(ELSE='foobar') INTO sx2.
233 LIST x sx0 TO sx2.
234 ])
235 AT_CHECK([pspp -O format=csv recode.sps], [0],
236   [Table: Data List
237 x,sx0,sx1,sx2
238 0,,xxx,foobar
239 1,abcdefghij,xxx,foobar
240 2,abcdefghij,,xyz
241 3,abcdefghij,xxx,xyz
242 4,abcdefghij,,xyz
243 5,abcdefghij,xxx,xyz
244 6,abcdefghij,,xyz
245 7,abcdefghij,xxx,foobar
246 8,abcdefghij,,foobar
247 9,abcdefghij,xxx,foobar
248 .,,xxx,xyz
249 ])
250 AT_CLEANUP
251
252 AT_SETUP([RECODE bug in COPY])
253 AT_DATA([recode.sps],
254   [DATA LIST LIST
255  /A (A1)
256  B (A1).
257
258 BEGIN DATA
259 1     2
260 2     3
261 3     4
262 END DATA.
263
264 ** Clearly, the else=copy is superfluous here
265 RECODE A ("1"="3") ("3"="1") (ELSE=COPY).
266 EXECUTE.
267 LIST.
268 ])
269 AT_CHECK([pspp -O format=csv recode.sps], [0],
270   [Table: Reading free-form data from INLINE.
271 Variable,Format
272 A,A1
273 B,A1
274
275 Table: Data List
276 A,B
277 3,2
278 2,3
279 1,4
280 ])
281 AT_CLEANUP
282
283 AT_SETUP([RECODE bug in COPY with INTO])
284 AT_DATA([recode.sps],
285   [DATA LIST LIST
286  /A (A1)
287  B (A1).
288
289 BEGIN DATA
290 1     2
291 2     3
292 3     4
293 END DATA.
294
295 STRING A1 (A1).
296 RECODE A ("1"="3") ("3"="1") (ELSE=COPY) INTO a1.
297 EXECUTE.
298 LIST.
299 ])
300 AT_CHECK([pspp -O format=csv recode.sps], [0],
301   [Table: Reading free-form data from INLINE.
302 Variable,Format
303 A,A1
304 B,A1
305
306 Table: Data List
307 A,B,A1
308 1,2,3
309 2,3,2
310 3,4,1
311 ])
312 AT_CLEANUP
313
314
315
316 AT_SETUP([RECODE increased string widths])
317
318 AT_DATA([recode.sps],[dnl
319 data list notable list /x (a1) y (a8) z *.
320 begin data.
321 a a         2
322 a two       2
323 b three     2
324 c b         2
325 end data.
326
327 recode x y ("a" = "first") .
328
329 list.
330 ])
331
332 AT_CHECK([pspp -O format=csv recode.sps], [1], [dnl
333 recode.sps:9: error: RECODE: At least one target variable is too narrow for the output values.
334
335 "recode.sps:9.19-9.25: note: RECODE: This recoding output value has width 5.
336     9 | recode x y (""a"" = ""first"") .
337       |                   ^~~~~~~"
338
339 "recode.sps:9.8-9.10: note: RECODE: Target variable x only has width 1.
340     9 | recode x y (""a"" = ""first"") .
341       |        ^~~"
342
343 Table: Data List
344 x,y,z
345 a,a,2.00
346 a,two,2.00
347 b,three,2.00
348 c,b,2.00
349 ])
350
351 AT_CLEANUP
352
353
354
355 AT_SETUP([RECODE crash on invalid dest variable])
356
357 AT_DATA([recode.sps],[dnl
358 DATA LIST LIST NOTABLE/x (f1) s (a4) t (a10).
359 MISSING VALUES x(9)/s('xxx').
360 BEGIN DATA.
361 0, '', ''
362 1, a, a
363 2, ab, ab
364 3, abc, abc
365 END DATA.
366
367 RECODE x (1=9) INTO ".
368 EXECUTE.
369 dnl "
370 ])
371
372 AT_CHECK([pspp -O format=csv recode.sps], [1], [ignore])
373
374 AT_CLEANUP
375
376
377 AT_SETUP([RECODE syntax errors])
378 AT_DATA([recode.sps], [dnl
379 DATA LIST LIST NOTABLE/n1 to n4 (F8.0) s1 (A1) s2 (A2) s3 (A3) s4 (A4).
380 RECODE **.
381 RECODE n1 **.
382 RECODE n1(**).
383 RECODE s1(**).
384 RECODE s1('x' THRU 'y').
385 RECODE n1(1=**).
386 RECODE n1(CONVERT).
387 RECODE n1(1=2)(1='x').
388 RECODE n1(1='x')(1=2).
389 RECODE s1(CONVERT)('1'='1').
390 RECODE n1(1=2 **).
391 RECODE n1(CONVERT).
392 RECODE s1(CONVERT) INTO n1 n2.
393 RECODE n1(1='1') INTO xyzzy.
394 RECODE n1(1='1').
395 RECODE s1('1'=1).
396 RECODE n1(1='1') INTO n2.
397 RECODE s1(CONVERT) INTO s2.
398 RECODE n1 TO n4(1='123456') INTO s1 TO s4.
399 ])
400 AT_CHECK([pspp -O format=csv recode.sps], [1], [dnl
401 "recode.sps:2.8-2.9: error: RECODE: Syntax error expecting variable name.
402     2 | RECODE **.
403       |        ^~"
404
405 "recode.sps:3.11-3.12: error: RECODE: Syntax error expecting `('.
406     3 | RECODE n1 **.
407       |           ^~"
408
409 "recode.sps:4.11-4.12: error: RECODE: Syntax error expecting number.
410     4 | RECODE n1(**).
411       |           ^~"
412
413 "recode.sps:5.11-5.12: error: RECODE: Syntax error expecting string.
414     5 | RECODE s1(**).
415       |           ^~"
416
417 "recode.sps:6.15-6.18: error: RECODE: THRU is not allowed with string variables.
418     6 | RECODE s1('x' THRU 'y').
419       |               ^~~~"
420
421 "recode.sps:7.13-7.14: error: RECODE: Syntax error expecting output value.
422     7 | RECODE n1(1=**).
423       |             ^~"
424
425 "recode.sps:8.11-8.17: error: RECODE: CONVERT requires string input values.
426     8 | RECODE n1(CONVERT).
427       |           ^~~~~~~"
428
429 recode.sps:9: error: RECODE: Output values must be all numeric or all string.
430
431 "recode.sps:9.13: note: RECODE: This output value is numeric.
432     9 | RECODE n1(1=2)(1='x').
433       |             ^"
434
435 "recode.sps:9.18-9.20: note: RECODE: This output value is string.
436     9 | RECODE n1(1=2)(1='x').
437       |                  ^~~"
438
439 recode.sps:10: error: RECODE: Output values must be all numeric or all string.
440
441 "recode.sps:10.20: note: RECODE: This output value is numeric.
442    10 | RECODE n1(1='x')(1=2).
443       |                    ^"
444
445 "recode.sps:10.13-10.15: note: RECODE: This output value is string.
446    10 | RECODE n1(1='x')(1=2).
447       |             ^~~"
448
449 recode.sps:11: error: RECODE: Output values must be all numeric or all string.
450
451 "recode.sps:11.11-11.17: note: RECODE: This output value is numeric.
452    11 | RECODE s1(CONVERT)('1'='1').
453       |           ^~~~~~~"
454
455 "recode.sps:11.24-11.26: note: RECODE: This output value is string.
456    11 | RECODE s1(CONVERT)('1'='1').
457       |                        ^~~"
458
459 "recode.sps:12.15-12.16: error: RECODE: Syntax error expecting `)'.
460    12 | RECODE n1(1=2 **).
461       |               ^~"
462
463 "recode.sps:13.11-13.17: error: RECODE: CONVERT requires string input values.
464    13 | RECODE n1(CONVERT).
465       |           ^~~~~~~"
466
467 recode.sps:14: error: RECODE: Source and target variable counts must match.
468
469 "recode.sps:14.8-14.9: note: RECODE: There is 1 source variable.
470    14 | RECODE s1(CONVERT) INTO n1 n2.
471       |        ^~"
472
473 "recode.sps:14.25-14.29: note: RECODE: There are 2 target variables.
474    14 | RECODE s1(CONVERT) INTO n1 n2.
475       |                         ^~~~~"
476
477 recode.sps:15: error: RECODE: All string variables specified on INTO must already exist.  (Use the STRING command to create a string variable.)
478
479 "recode.sps:15.23-15.27: note: RECODE: There is no variable named xyzzy.
480    15 | RECODE n1(1='1') INTO xyzzy.
481       |                       ^~~~~"
482
483 "recode.sps:16.10-16.16: error: RECODE: INTO is required with numeric input values and string output values.
484    16 | RECODE n1(1='1').
485       |          ^~~~~~~"
486
487 "recode.sps:17.10-17.16: error: RECODE: INTO is required with string input values and numeric output values.
488    17 | RECODE s1('1'=1).
489       |          ^~~~~~~"
490
491 "recode.sps:18.23-18.24: error: RECODE: Type mismatch: cannot store string data in numeric variable n2.
492    18 | RECODE n1(1='1') INTO n2.
493       |                       ^~"
494
495 "recode.sps:19.25-19.26: error: RECODE: Type mismatch: cannot store numeric data in string variable s2.
496    19 | RECODE s1(CONVERT) INTO s2.
497       |                         ^~"
498
499 recode.sps:20: error: RECODE: At least one target variable is too narrow for the output values.
500
501 "recode.sps:20.19-20.26: note: RECODE: This recoding output value has width 6.
502    20 | RECODE n1 TO n4(1='123456') INTO s1 TO s4.
503       |                   ^~~~~~~~"
504
505 "recode.sps:20.29-20.41: note: RECODE: Target variable s1 only has width 1.
506    20 | RECODE n1 TO n4(1='123456') INTO s1 TO s4.
507       |                             ^~~~~~~~~~~~~"
508 ])
509 AT_CLEANUP