Using Compute Blocks to Enhance PROC REPORT Output Laurie Buchanan, Healthsource, Inc. LINE statements within a compute block can create customized summary lines but since the LINE statement is not executable, subtotals are created for every group. Using COMPUTE blocks we can check for groups of greater than one row and create a character variable containing the subtotal values. When the group contains only one row this variable is set to missing. The LINE statement will execute at every break but the value of the variable printed changes producing the desired result. Abstract Compute blocks are a powerful feature of PROC REPORT, allowing for the addition of programming statements to the REPORT procedure. This paper will demonstrate the use of compute blocks to conditionally assign formats to rows of the report and to produce subtotals only when a grouping contains more than one row. Introduction A compute block is a group of programming statements within PROC REPORT that is executed for every row of the report or at a specific location in the report. Compute blocks can be used to create variables not on the incoming data set, perform calculations, set display attributes such as formats, and produce customized summary lines. This same method of counting rows is used to control the formatting of specific rows using the CALL DEFINE statement within a compute block. For this paper, we will produce a report on laboratory service costs summarized by place of service and vendor (see FIGURE 1). The data set contains variables for place of service (pos), vendor, total cost (cost_96 and cost_97), per member per month cost (pmpm_96 and pmpm_97), and member month counts (mm_96 and mm_97). The BREAK statement with the SUMMARIZE option is an easy way to produce subtotals after every group. However, when a group contains only one item, a subtotal is not needed and crowds the report. The Code SURF UHSRUW GDWD ODEVYFV VSOLW PLVVLQJ QRZG KHDGOLQH KHDGVNLS FRO SRV RUGBYHQG YHQGRU <( FRVWB SPSPB <7' FRVWB SPSPB 9$5,$1&( YDUBSPSP YDUBSFW PPB PPB GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH GHILQH SRV RUGBYHQG YHQGRU FRVWB SPSPB FRVWB SPSPB YDUBSPSP YDUBSFW PPB PPB JURXS JURXS JURXS DQDO\VLV DQDO\VLV DQDO\VLV DQDO\VLV FRPSXWHG FRPSXWHG DQDO\VLV DQDO\VLV VXP VXP VXP VXP PHDQ PHDQ 3/$&( 2) 6(59,&( RUGHU GDWD QRSULQW 9(1'25 $02817 IRUPDW FRPPD 3030 IRUPDW FRPPD $02817 IRUPDW FRPPD 3030 IRUPDW FRPPD 3030 IRUPDW FRPPD 3&7 IRUPDW SHUFHQW QRSULQW QRSULQW ZLGWK ZLGWK ZLGWK ZLGWK ZLGWK ZLGWK ZLGWK ZLGWK FRPSXWH EHIRUH SRV FRXQW HQGFRPS FRPSXWH FRVWB LI YHQGRU QH WKHQ FRXQW LI YHQGRU RU FRXQW WKHQ FDOO GHILQHBFROBIRUPDWGROODU HQGFRPS FRPSXWH SPSPB LI YHQGRU RU FRXQW WKHQ FDOO GHILQHBFROBIRUPDWGROODU HQGFRPS FRPSXWH FRVWB 1 LI YHQGRU RU FRXQW WKHQ FDOO GHILQHBFROBIRUPDWGROODU HQGFRPS FRPSXWH SPSPB LI YHQGRU RU FRXQW WKHQ FDOO GHILQHBFROBIRUPDWGROODU HQGFRPS FRPSXWH YDUBSPSP YDUBSPSP URXQGSPSPBVXP URXQGSPSPBVXP LI YHQGRU RU FRXQW WKHQ FDOO GHILQHBFROBIRUPDWGROODU HQGFRPS FRPSXWH YDUBSFW LI URXQGSPSPBVXP WKHQ YDUBSFW HOVH YDUBSFW URXQGYDUBSPSP URXQGSPSPBVXP HQGFRPS FRPSXWH DIWHU SRV OHQJWK WH[W WH[W LI FRXQW! WKHQ GR WH[W BBBBBBBBBB BBBBBBB BBBBBBBBBB BBBBBBB BBBBBBB BBBBBBB WH[W SXWFRVWBVXPGROODU__ __SXWSPSPBVXPGROODU__ SXWFRVWBVXPGROODU__ __SXWSPSPBVXPGROODU__ SXWYDUBSPSPGROODU__ __SXWYDUBSFWSHUFHQW HQG HOVH GR WH[W WH[W HQG OLQH # WH[W OLQH # WH[W OLQH HQGFRPS __ __ FRPSXWH DIWHU SRV 727$/ OLQH OLQH # 0(0%(5 0217+6 PPBPHDQ FRPPD PPBPHDQ FRPPD HQGFRPS UEUHDN DIWHU RO XO VXPPDUL]H UXQ block with the first analysis variable (cost_96) causes the programming statements in the compute block to execute for every row. Since PROC REPORT does not repeat the values of group variables row to row, pos is missing on all rows but the first. Therefore, one is added to the counter when the subgroup, vendor is not missing. A dollar format overrides the format specified by the DEFINE statement on the first row of a group, the subtotal row, and the grand total row. The first row is easily identified by count=1. The grand total and subtotal rows are identified by a missing value for the subgroup. The automatic variable _COL_ refers to the current column named in the COMPUTE statement. A compute block with the CALL DEFINE statement is set up for each variable to be formatted this way. Compute blocks can calculate variables not on the incoming data set. A DEFINE statement is needed for each computed variable and the variables must be added to the COLUMN statement. To count the rows in each group, a DATA step variable is created and initialized to zero at the start of a group. Unlike REPORT variables (variables defined in the COLUMN statement) DATA step variables are not reset to missing at the start of a new row. The BEFORE argument in the COMPUTE statement attaches the compute block to a location. Here, the location is before each change in the group variable pos. This compute block counts the rows in a group. Because a compute block must be associated with a report item or location, associating the compute 2 The LINE statements write the text variables with either missing values or the subtotals at each break. This line changes the text in the default summary line produced by the RBREAK statement. COMPUTE AFTER associates the compute block with the end of the report. LINE statements are used to add text at the end of the report. A break is created after each change in the value of pos by the COMPUTE AFTER POS statement. The counter is checked for values greater than one. Two text variables are set up. The length is set to the sum of the widths of the columns to be subtotaled and the space between them. The column widths are set in the DEFINE statement and the default column space is 2. When the counter is greater than one, the first text variable is set to the underline characters for the columns. The second is a series of concatenated put statements that use the SUM statistic to calculate the subtotals for the group. Otherwise the two text variables are set to missing. The position to place the text is calculated by summing the widths of the columns and column spaces to the left of the text and adding that to the position where PROC REPORT starts the report. Conclusion By taking full advantage of the power of compute blocks, it is possible to create professional looking reports using PROC REPORT. Author Contact Laurie Buchanan Healthsource, Inc. 2 College Park Drive Hooksett, NH 03106 FIGURE 1 727$/ 0(',&$/ &267 /$%25$725< 6(59,&(6 $1$/<6,6 cccccc <( cccccc ccccc <7' cccccc ccc 9$5,$1&( ccc 3/$&( 2) 6(59,&( 9(1'25 $02817 3030 $02817 3030 3030 3&7 cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ,1'(3(1'(17 /$%6 $%& 3$7+2/2*< %25,6 /$%25$725,(6 72:(5 /$%6 5-% $662&,$7(6 +,// ',$*1267,&6 BBBBBBBBBB BBBBBBB BBBBBBBBBB BBBBBBB BBBBBBB BBBBBBB ,13$7,(17 +263,7$/ 0(',&$/ &(17(5 *(1(5$/ +263,7$/ /(( &+,/'5(16 +263 %52:1 0(' &(17(5 %21 +263,7$/ BBBBBBBBBB BBBBBBB BBBBBBBBBB BBBBBBB BBBBBBB BBBBBBB 2873$7,(17 +263,7$/ 0(',&$/ &(17(5 *(1(5$/ +263,7$/ 0867$5' &/,1,& .)% +263,7$/ &/<'( &(17(5 BBBBBBBBBB BBBBBBB BBBBBBBBBB BBBBBBB BBBBBBB BBBBBBB 3+<6,&,$16 2)),&(6 $// 27+(5 cccccccccccccccccccc 727$/ cccccccccccccccccccc 0(0%(5 0217+6 cccccccccc ccccccc cccccccccc cccccccccc ccccccc cccccccccc ccccccc ccccccc 3 ccccccc ccccccc ccccccc ccccccc (603) 268-7164 buchanl@hlthsrc.com LBuchanan7@aol.com