Help using Base SAS procedures

Debug a COMPUTE block in PROC REPORT

Reply
Contributor
Posts: 38

Debug a COMPUTE block in PROC REPORT

my condition logic is not working... Any suggestions on how to see the value for reccnt.sum?

compute after entityid;
if reccnt.sum > 1
then do;
pct_ip=inprogress.sum/reccnt.sum;
pct_ur=unreachable.sum/reccnt.sum;
pct_nc=not_called.sum/reccnt.sum;
pct_pe=PE.sum/reccnt.sum;
pct_cw=casesworked.sum/reccnt.sum;
pct_rqd=requeued.sum/reccnt.sum;
line @2 'Entity Statistics - Cases Pulled: ' pulledcount.sum 6.0 +2 'Avg Pull Count: ' pulledmean 7.2
' Avg Time Spent: ' Time_Spentmean Time.
' Total Calls: ' phone_calls.sum 7.1 +2 'Avg Calls: ' ph_call_mean 7.2 +2 '% Not Called: ' pct_nc percent9.2
' % Unreachable: ' pct_ur percent9.2 +2 '% In Progress: ' pct_ip percent9.2;
line @182 '% PE: ' pct_pe percent9.2 +2 '% Cases Worked: ' pct_cw percent9.2 +2 '% Requeued: ' pct_rqd percent9.2;
end;
line ' ';
endcomp;
Respected Advisor
Posts: 3,777

Re: Debug a COMPUTE block in PROC REPORT

I use the undocumented SEENUM and SEECHAR function to help debug compute blocks. The functions "PUT" values to the log.

[pre]
rc = seenum(reccnt.sum,'RECCNT.SUM=');
[/pre]

However the sum of probably missing. You may need to "RETAIN" it's value from when it was computed, using proc reports temporary variable(s).

The REPORT Procedure’s Temporary Variable: What is it? Why Do I Care?
http://www2.sas.com/proceedings/sugi31/060-31.pdf


I see that I had overlooked the LINE statements in the DO and assume that is the part that needs debugging. Like the others mentioned, it don't work that way.

You could resort to a little trick that might work for you. You will have to translate your current line statements into strings. See this useage note.
http://support.sas.com/kb/37/763.html

For details regarding the simulated conditional line statement.
SAS Super FREQ
Posts: 8,743

Re: Debug a COMPUTE block in PROC REPORT

Hi:
You do NOT show your entire PROC REPORT code or your SAS log. These would be helpful. Generally, however, one reason that a COMPUTE block does not work is that you have made some assumption that is in error because you either ignore or don't understand the left to right order of processing of the items in your COLUMN statement. Let's take a simple example:

[pre]
proc report data=sashelp.class nowd;
column name numvar age sex height weight;
define name /order;
define numvar / computed;
define sex / display;
define age / sum;
define height /sum;
define weight /sum;
compute numvar;
if sex = 'F' then temp = height.sum * weight.sum - age.sum;
else if sex = 'M' then temp = height.sum*weight.sum;
numvar = temp;
endcomp;
run;
[/pre]

For example, in the above code, you will NOT get any errors in the LOG, but the column for NUMVAR, which you want to compute conditionally using a temporary variable TEMP ( based on the value for the SEX variable) will just contain missing values -- because NUMVAR is in the COLUMN statement before AGE, HEIGHT, WEIGHT and SEX -- all of which are needed for the correct computation of TEMP and NUMVAR. Since PROC REPORT builds report rows by placing report row information from LEFT to RIGHT on the report, the column for NUMVAR is placed before the columns for SEX, AGE, HEIGHT or WEIGHT. Therefore, when the COMPUTE block for NUMVAR executes, it's as if there was NOTHING to test and nothing to multiply.

In order to generate a value for NUMVAR, the correct order of items in the COLUMN statement is:
[pre]
column name age sex height weight numvar;
[/pre]

This would be the ONLY thing you have to change to make the above program work.

Remember that the PROC REPORT method of building a report is NOT like the DATA step method of operating...for example, there is NO Program Data Vector and no "buffer" areas ... each report row is built one item (column) at a time, from left to right. So, for example, in the above COLUMN statement, when the value for AGE is placed on the report row, there is no visibility of the value for SEX or HEIGHT on the same row. However, by the time NUMVAR needs to have its COMPUTE block executed, all the other variables have been placed on the report row, so they are available for use in the calculation of NUMVAR.

And, just as an FYI, depending on your ODS destination, techniques like @2 and +2 typically do not work for ODS HTML, ODS RTF and ODS PDF -- they are LISTING only techniques .. so if your ultimate destination is something other than LISTING, you may want to use different techniques for placing your LINE output.

If you were willing to post ALL your REPORT code and a sample of fake data or a program that made fake data, it might be possible to help you figure out what was going on. If it's not the order of variables on the COLUMN statement, then I'm betting that it's some combination of ORDER/GROUP items that's making reccnt.sum not available at the break on entryid. Also, do note this restriction statement from the PROC REPORT documentation about LINE statement execution:
You cannot use the LINE statement in conditional statements (IF-THEN, IF-THEN/ELSE, and SELECT) because it is not executed until PROC REPORT has executed all other statements in the compute block.


cynthia
Valued Guide
Posts: 632

Re: Debug a COMPUTE block in PROC REPORT

LINE statements cannot be conditionally executed in a compute block. This is very different from PUT statements in the DATA step. Here both of the LINE statements will be executed regardless of the value of RECCNT.SUM.

The effective form of your compute block becomes something like:
[pre]
if .....do;
....
end;
line ....;
line ' ';
[/pre]
Contributor
Posts: 38

Re: Debug a COMPUTE block in PROC REPORT

Thanks to all that replied (DataNULL, Cynthia and ArtC) for your time and knowledge. The sharing of knowledge is invaluable and much appreciated. I learned many new things about proc report. For example I was unaware of the left to right order of things and that you cannot conditionally use the LINES statement in a compute statement.

Regards,
JimBaillie
Ask a Question
Discussion stats
  • 4 replies
  • 270 views
  • 0 likes
  • 4 in conversation