Date: Mon, 19 Apr 2004 16:03:10 -0400
Reply-To: SAS Bigot <sas_bigot@ML1.NET>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: SAS Bigot <sas_bigot@ML1.NET>
Subject: Re: Conditional formatting in compute blocks with Proc Report
In-Reply-To: <c0199144.0404190458.65ee6990@posting.google.com>
Content-Type: text/plain; charset="iso-8859-1"
I cannot go into great detail why you get the results that you do, but
I'll try to explain briefly. The online doc for proc report has a few
examples how a report is constructed, step by step. I refer you to the
doc for detailed study.
The report procedure distinguishes between report variables and data step
variables. They differ in 2 major ways. First, report variables are those
that are defined in the columns of the report, and data step variables
only appear in one or more compute blocks. Second, data step vars are
initialized at the beginning of the proc and their values of retained
until changed. Report variables are initialized before each line in the
report is contructed.
Cat1 is a report variable. It is also specifically defined as a group
variable. When proc report processes the dummy data set, it first builds
a temp file that contains all of the calculations and stats for the
detail and summary lines. Since Cat1 is a group variable, it will contain
a value only for each change in its value. In other words, its value is
not repeated in every row of the temp file. Test this out by changing
your if statement in your compute block to 'if missing(cat1)...'.
To get the results you desire, create a data step variable that captures
and retains the value of Cat1 and use the data step variable in your if
statement. Add the following compute block before the others:
compute before Cat1;
t_cat1 = Cat1;
endcomp;
The data step variable, t_cat1, will hold the value of Cat1 throughout
each iteration of the detail rows.
Then change your if statement to test the value of t_cat1:
if t_cat1 = 3 then do;
That will do it.
----- Original message -----
From: "rambles" <baxter@POSTMASTER.CO.UK>
To: SAS-L@LISTSERV.UGA.EDU
Date: Mon, 19 Apr 2004 05:58:27 -0700
Subject: Conditional formatting in compute blocks with Proc Report
Hi everybody.
I'm trying to write a reporting system based on Lisa M. Schneider's
excellent paper "Format challenges with Proc Report"
(http://www2.sas.com/proceedings/sugi26/p089-26.pdf). However, I've
decided to make a couple of adaptations - and I'm beginning to wish I
hadn't! Put simply, I'm trying to compute column variables ('_Cn_'
variables) based on the value of a data step variable. However, all
is not going as planned. For example, this code works...
==============
data dummy;
INPUT Cat1 3. Cat2 3. _Cat1 & $100. _Cat2 & $100. Classvar & 8.
leftcol & 8. rightcol & 8.;
DATALINES;
2 1 Age (#) N 1 6 .
2 1 Age (#) N 2 6 .
2 2 Age (#) Mean 1 26.166666667 100
2 2 Age (#) Mean 2 24.333333333 0
3 1 Sex Male 1 6 100
3 1 Sex Male 2 6 100
3 2 Sex Female 1 0 0
3 2 Sex Female 2 0 0
;
run;
PROC REPORT DATA=dummy MISSING HEADLINE HEADSKIP NOWINDOWS SPLIT="|"
OUT=_out;
COLUMN Cat1 _Cat1 Cat2 _Cat2 classvar,(leftcol newleft rightcol
newright);
DEFINE Cat1 / GROUP ORDER=INTERNAL NOPRINT;
DEFINE _Cat1 / GROUP WIDTH=20 ' ' ID FLOW;
DEFINE Cat2 / GROUP ORDER=INTERNAL NOPRINT;
DEFINE _Cat2 / GROUP WIDTH=12 ' ' ID;
DEFINE classvar / ACROSS ORDER=INTERNAL ' ' format=best12.;
DEFINE leftcol / ANALYSIS NOPRINT;
DEFINE newleft / COMPUTED WIDTH=10 ' ';
DEFINE rightcol / ANALYSIS NOPRINT;
DEFINE newright / COMPUTED WIDTH=8 ' ';
COMPUTE newleft / CHAR;
_C6_ = PUT(_C5_, dollar6.1);
_C10_ = PUT(_C9_, dollar6.1);
ENDCOMP;
COMPUTE newright / CHAR;
_C8_ = PUT(_C7_, 6.1);
_C12_ = PUT(_C11_, 6.1);
ENDCOMP;
BREAK AFTER Cat1 / SKIP;
RUN;
===============
which gives me the following (correct) output...
===============
1 2
_____________________________________________________________________
Age (#) N $6.0 $6.0
Mean $26.2 100.0 $24.3 0.0
Sex Male $6.0 100.0 $6.0 100.0
Female $0.0 0.0 $0.0 0.0
=======
Now, I only want the compute block for 'newright' to work for the
'sex' variable. This is equivalent, from the above code, to when
Cat1=3. However, if I add the condition to the 'newright' compute
block (in full)....
=======
COMPUTE newright / CHAR;
IF Cat1=3 THEN DO;
_C8_ = PUT(_C7_, 6.1);
_C12_ = PUT(_C11_, 6.1);
END;
ENDCOMP;
=======
I get the following output...
=======
1 2
____________________________________________________________________
Age (#) N $6.0 $6.0
Mean $26.2 $24.3
Sex Male $6.0 100.0 $6.0 100.0
Female $0.0 $0.0
=======
The program has rightly prevented age (Cat1=2) from being processed
but the 'Female' part of sex has been neglected too (always the way,
I'm told...)! In my mind, the 'Female' row should *also* show the
formatted value. Looking at the output dataset confirms that this
compute block is only working on the first row.
Does anybody have any idea where I'm going wrong?
Many thanks, Rich
--
http://www.fastmail.fm - Faster than the air-speed velocity of an
unladen european swallow