DATA Step, Macro, Functions and more

Retain not retaining - HELP !

Reply
Occasional Contributor
Posts: 17

Retain not retaining - HELP !

SAS-Ler's
I have what should be a simple program with a file of question numbers (qnum) and responses (1-4). I want to count up all the responses (totaling) for one question and output one record that summarizes the number of 1s (in variable r1), the number of 2s in r2, etc. I can initialize r1--r4 to all zeros, but when I go to get the counts (via if statements), r1--r4 are obviously not being retained - they are being set to count of 1 for whatever was in the last observtion,
Here is the code :
data meld;
input qnum ntst respno;

datalines;
1 2 1
1 3 2
1 2 3
1 4 4
1 2 5
1 1 6
1 1 7
2 1 1
2 3 2
2 3 3
2 3 4
2 3 5
2 1 6
2 2 7
3 1 1
3 3 2
3 3 3
3 2 4
3 3 5
3 4 6
3 2 7
;


data final;
%let studno=7; * Number of responses per question number;
array ress[4] r1-r4;
do i = 1 to 4;
ress = 0;
end;
retain r1--r4;
set meld;

%put The value of studno is &studno;

if ntst = 1 then r1 = r1 + 1;
if ntst = 2 then r2 = r2 + 1;
if ntst = 3 then r3 = r3 + 1;
if ntst = 4 then r4 = r4 + 1;

put 'qnum ntst respno : ' qnum ntst respno ' r1 thru r4 : ' r1 r2 r3 r4 ;

if respno = &studno then output;

run;


proc print data = final;
title 'Final data set';
run;

For qnum one, r1--r4 should be 2 3 1 1 instead of all zeroes except for r1 (indicating the last response (for qnum = 1) is a 1. SAS computes 1 0 0 0 instead.

Can any of you SAS experts out there tell me what is wrong ? I've tried various fixes without success.

Barry Walton
Barry.Walton@millersville.edu
Super Contributor
Super Contributor
Posts: 3,174

Re: Retain not retaining - HELP !

Posted in reply to enginemane44
It would be more useful to post your SAS-generated log with your 'executed code' revealed, rather than just the program statements itself -- the info posted is useful to a point.

First off, the line below would normally generate a SAS ERROR (rather than generating some warnings or curious SAS notes):

array ress[4] r1-r4;
do i = 1 to 4;
ress = 0;
end;

Here's the error:

ERROR: Illegal reference to the array RESS.

There is no reason to have the assignment statement for "RESS" -- the DO loop is not needed.

Also, SAS numeric variables cannot be operated on when they have a missing value condition in some conditions -- your IF / THEN ; statement needs to be revised to use the SUM(R1,1); construct, as one example.

Scott Barry
SBBWorks, Inc.
Occasional Contributor
Posts: 17

Re: Retain not retaining - HELP !

Scott,
I think you wanted to see this - from the SAS log - look at the output from the PUT statement as the data step executes.
28
29 data final;
30 %let studno=7; * Number of responses per question number;
31 array ress[4] r1-r4;
32 do i = 1 to 4;
33 ress = 0;
34 end;
35 retain r1--r4;
36 set meld;
37
38 %put The value of studno is &studno;
The value of studno is 7
39
40 if ntst = 1 then r1 = r1 + 1;
41 if ntst = 2 then r2 = r2 + 1;
42 if ntst = 3 then r3 = r3 + 1;
43 if ntst = 4 then r4 = r4 + 1;
44
45 put 'qnum ntst respno : ' qnum ntst respno ' r1 thru r4 : ' r1 r2 r3 r4 ;
46
47 if respno = &studno then output;
48
49 run;

qnum ntst respno : 1 2 1 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 1 2 3 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 4 4 r1 thru r4 : 0 0 0 1
qnum ntst respno : 1 2 5 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 1 6 r1 thru r4 : 1 0 0 0
qnum ntst respno : 1 1 7 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 1 1 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 3 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 4 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 5 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 1 6 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 2 7 r1 thru r4 : 0 1 0 0
qnum ntst respno : 3 1 1 r1 thru r4 : 1 0 0 0
qnum ntst respno : 3 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 3 3 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 2 4 r1 thru r4 : 0 1 0 0
qnum ntst respno : 3 3 5 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 4 6 r1 thru r4 : 0 0 0 1
qnum ntst respno : 3 2 7 r1 thru r4 : 0 1 0 0
NOTE: There were 21 observations read from the data set WORK.MELD.
NOTE: The data set WORK.FINAL has 3 observations and 8 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.01 seconds


50
51
52 proc print data = final;
53 title 'Final data set';
54 run;

NOTE: There were 3 observations read from the data set WORK.FINAL.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds

And here is the output from PROC PRINT :
28
29 data final;
30 %let studno=7; * Number of responses per question number;
31 array ress[4] r1-r4;
32 do i = 1 to 4;
33 ress = 0;
34 end;
35 retain r1--r4;
36 set meld;
37
38 %put The value of studno is &studno;
The value of studno is 7
39
40 if ntst = 1 then r1 = r1 + 1;
41 if ntst = 2 then r2 = r2 + 1;
42 if ntst = 3 then r3 = r3 + 1;
43 if ntst = 4 then r4 = r4 + 1;
44
45 put 'qnum ntst respno : ' qnum ntst respno ' r1 thru r4 : ' r1 r2 r3 r4 ;
46
47 if respno = &studno then output;
48
49 run;

qnum ntst respno : 1 2 1 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 1 2 3 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 4 4 r1 thru r4 : 0 0 0 1
qnum ntst respno : 1 2 5 r1 thru r4 : 0 1 0 0
qnum ntst respno : 1 1 6 r1 thru r4 : 1 0 0 0
qnum ntst respno : 1 1 7 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 1 1 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 3 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 4 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 3 5 r1 thru r4 : 0 0 1 0
qnum ntst respno : 2 1 6 r1 thru r4 : 1 0 0 0
qnum ntst respno : 2 2 7 r1 thru r4 : 0 1 0 0
qnum ntst respno : 3 1 1 r1 thru r4 : 1 0 0 0
qnum ntst respno : 3 3 2 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 3 3 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 2 4 r1 thru r4 : 0 1 0 0
qnum ntst respno : 3 3 5 r1 thru r4 : 0 0 1 0
qnum ntst respno : 3 4 6 r1 thru r4 : 0 0 0 1
qnum ntst respno : 3 2 7 r1 thru r4 : 0 1 0 0
NOTE: There were 21 observations read from the data set WORK.MELD.
NOTE: The data set WORK.FINAL has 3 observations and 8 variables.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.01 seconds


50
51
52 proc print data = final;
53 title 'Final data set';
54 run;

NOTE: There were 3 observations read from the data set WORK.FINAL.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds

And here is the output from PROC PRINT :
Final data set 14:41 Friday, January 28, 2011 1
Obs r1 r2 r3 r4 i qnum ntst respno
1 1 0 0 0 5 1 1 7
2 0 1 0 0 5 2 2 7
3 0 1 0 0 5 3 2 7

Also, the assigment statement in the do loop reads 'ress=0'; not 'ress=0';.
Any ideas ?

Barry Walton
Contributor
Posts: 29

Re: Retain not retaining - HELP !

Posted in reply to enginemane44
trying changing :

do i = 1 to 4;
ress = 0;
end;

to:
if _n_ = 1 then do i = 1 to 4;
ress(i) = 0;
end;

I would also move:
set meld; right after data final;

data final;
set meld;
other statements
Occasional Contributor
Posts: 17

Re: Retain not retaining - HELP !

SAS-Lers,

THANK YOU - 'garybald' had just what the doctor ordered ! I see now my mistake
was neglecting to set the r1--r4 ONLY ON THE FIRST ITERATION OF THE DATA STEP (i.e. _N_=1). I did what you recommended and that worked. Again a big
THANK YOU !

Barry Walton
Super User
Posts: 11,343

Re: Retain not retaining - HELP !

Posted in reply to enginemane44
Another thing is that RETAIN can be used to set an intial value such as 0 for the variables.
N/A
Posts: 0

Re: Retain not retaining - HELP !

Posted in reply to enginemane44
hello,

another solution based on automatic by variables first and last. of course your data
should be sorted by qnum variable:
[pre]
data final;
set meld;

by qnum;

array resr{4} res1 res2 res3 res4;

if first.qnum then do i=1 to dim(resr);
call missing(resr{i});
end;

resr{ntst}+1;

if last.qnum then output;

drop i;

run;

[/pre]

Marius
Ask a Question
Discussion stats
  • 6 replies
  • 200 views
  • 0 likes
  • 5 in conversation