| |
The Problem
There are 2
problems with this code:
-
Four
records are output because, unless an output statement is explicitly
used in the Data Step, a record is automatically written at the end of the
step, such as when SAS meets a return statement.
On the 4th iteration of the Data Step SAS finds no more data and jumps to the
lastrec label, and writes another observation when it gets to the
return statement.
-
In the
if statement, the put function returns a character string of length
1, the length of the label.
When the value '130' is used, the value is not matched and, since no 'other='
was defined in the format, the original value is returned - truncated to '1',
the same as the valid results!!
The Solution
"Don't be lazy. Be explicit.".
-
Use the
output statement with the if test. Its absence in the
lastrec section will ensure no extra record is written.
-
Always
use 'other=' with your formats and leave nothing to chance.
Specifying a length on the format name i.e. put(recid, $valid3.) would also
work in this case.
The code could be amended like
this...
|
/* Define valid values */
proc
format;
value
$valid
'120'-'129',
'140'-'145'
=
'1'
other='X';
run;
/* Read and keep valid records */
data
valid (keep = recid);
infile
cards
missover
eof=lastrec;
input
recid $;
if
put(recid,
$valid.)
=
'1'
then
output;
valid_recs +
1;
return;
lastrec:
put
valid_recs=;
return;
cards;
123
130
141
;
run;
proc
print;
run;
|
/* Always use other=
*/
/* Explicitly output valid recs. */
|
"Expected"
Output:
valid_recs=2
The SAS System
Obs recid
1 123
2 141
|
Actual Output:
valid_recs=2
The SAS System
Obs recid
1 123
2
141
|
|
|