8.5 Custom Tabular Reports with PROC REPORT & PROC TABULATE

Key Takeaways

  • PROC REPORT combines features of PROC PRINT, PROC MEANS, and PROC TABULATE, using a COLUMN statement to define columns and DEFINE statements for usage types.
  • The DEFINE statement usage types in PROC REPORT include DISPLAY, ORDER, GROUP, ANALYSIS, and ACROSS.
  • The ACROSS usage type in PROC REPORT transposes unique values of a categorical variable into horizontal column headers across the report.
  • PROC TABULATE builds multi-dimensional tables using page, row, and column expressions separated by commas (page, row, column).
  • In PROC TABULATE syntax, the asterisk (*) operator nests variables within table dimensions, while a blank space concatenates variables side-by-side.
Last updated: August 2026

8.5 Custom Tabular Reports with PROC REPORT & PROC TABULATE

When standard row listings from PROC PRINT or basic summary outputs from PROC MEANS do not satisfy complex business reporting requirements, Base SAS provides two sophisticated custom reporting procedures: PROC REPORT and PROC TABULATE. Both procedures can calculate summary statistics, format hierarchical matrix structures, and produce publication-ready reports across ODS destinations. Mastering their statements, usage types, dimension operators, and compute block rules is a key focus area on the SAS Certified Specialist Base Programming exam.


1. PROC REPORT Architecture & Mechanics

PROC REPORT combines the detail-listing capabilities of PROC PRINT with the statistical summary features of PROC MEANS and the formatting power of PROC TABULATE in a single unified interface.

Essential Statements in PROC REPORT:

  • COLUMN variable-list;: A mandatory statement that specifies all variables and calculated items to include in the report, strictly defining their left-to-right visual column sequence.
  • DEFINE variable / usage-type 'column-header' options;: Specifies how a particular variable is processed, its header label, formatting, and alignment.
proc report data=sashelp.shoes;
   column Region Product Sales Returns Profit;
   define Region / group "Sales Region";
   define Product / display "Product Line";
   define Sales / analysis sum format=dollar14.2 "Gross Sales";
run;

2. PROC REPORT DEFINE Usage Types

The usage type specified after the slash (/) in a DEFINE statement dictates how PROC REPORT evaluates and renders that column during report execution:

Usage TypeBehavioral Description & Exam Rules
DISPLAYDisplays raw observation values for each row (like PROC PRINT). Default usage for character variables if no grouping or ordering occurs.
ORDERDisplays detail rows ordered by the formatted values of the variable, but suppresses repeating duplicate values in consecutive rows for clean visual layout.
GROUPCollapses observations sharing identical formatted values into a single summary row. Numeric variables in the report are automatically summarized across the group.
ANALYSISCalculates a statistic for a numeric variable (default statistic is SUM). Default usage for numeric variables in PROC REPORT.
ACROSSPivots/transposes unique values of a categorical variable horizontally into column headers across the top of the report matrix.
COMPUTEDDefines a new column whose values are calculated dynamically using DATA step expressions inside a COMPUTE block.
/* Demonstrating ACROSS vs GROUP */
proc report data=sashelp.shoes;
   column Region Product, (Sales Returns);
   define Region / group;
   define Product / across;
   define Sales / analysis sum format=dollar12.;
   define Returns / analysis sum format=dollar12.;
run;

Exam Tip - ORDER vs. GROUP: ORDER preserves every detail row in the dataset (it merely suppresses repeating text in column 1). GROUP collapses multiple detail rows into a single aggregated summary row!


3. Compute Blocks in PROC REPORT

PROC REPORT allows custom programming logic using COMPUTE ... ENDCOMPUTE blocks to calculate new column values, insert text lines, or format cells conditionally.

proc report data=sashelp.shoes;
   column Region Sales Returns NetSales;
   define Region / group;
   define Sales / analysis sum;
   define Returns / analysis sum;
   define NetSales / computed format=dollar14.2 "Net Sales";
   
   /* Compute block for target computed column */
   compute NetSales;
      NetSales = Sales.sum - Returns.sum;
   endcompute;
run;

Rules for Compute Blocks:

  1. Referencing Variables: When referencing an ANALYSIS variable inside a compute block, specify both the variable name and statistic (e.g., Sales.sum or Returns.mean).
  2. Execution Timing: Compute blocks execute during the report formatting phase after data grouping and statistic calculations are completed.
  3. LINE Statement: Inserts custom text lines above or below summary breaks (e.g., compute after Region; line "End of Region"; endcompute;).

4. PROC TABULATE Architecture & Dimensions

PROC TABULATE constructs complex multi-dimensional tables (hierarchical tables with page, row, and column dimensions) using concise expression syntax.

Core Statements in PROC TABULATE:

  • CLASS variable-list;: Identifies categorical variables used for grouping into row, column, or page headers.
  • VAR variable-list;: Identifies numeric analysis variables to be summarized.
  • TABLE <page-expression,> <row-expression,> column-expression / options;: Defines the structural layout and dimensions of the report table.
proc tabulate data=sashelp.shoes;
   class Region Product;
   var Sales;
   table Region, Product * Sales * mean;
run;

5. Dimension Syntax and Operators in PROC TABULATE

The TABLE statement uses specific punctuation operators to construct table dimensions:

1. Dimension Separator: The Comma (,)

Commas separate table dimensions in the TABLE statement. A table can have up to 3 dimensions:

  • 1 Dimension: TABLE column-expression;
  • 2 Dimensions: TABLE row-expression , column-expression;
  • 3 Dimensions: TABLE page-expression , row-expression , column-expression;

2. Nesting Operator: The Asterisk (*)

The asterisk nests elements within a dimension, placing categories inside another category.

3. Concatenation Operator: Blank Space ( )

A space concatenates elements side-by-side within the same dimension.

4. Grouping Operator: Parentheses ()

Parentheses group elements to apply an operator (such as nesting or a statistic) across multiple variables simultaneously.

5. Summary Keyword: ALL

Adding ALL creates summary total rows, columns, or pages across categorical levels.

/* Advanced PROC TABULATE Example with Nesting, Concatenation, and ALL */
proc tabulate data=sashelp.shoes;
   class Region Product;
   var Sales Returns;
   
   /* Row dimension: Region concatenated with ALL */
   /* Column dimension: Product nested with Sales and Returns statistics */
   table Region all,
         Product * (Sales*sum Returns*mean)
         / box="Sales Analysis" misstext="N/A";
run;
  • BOX="text": Customizes the top-left empty corner box of a 2-D table.
  • MISSTEXT="text": Replaces blank missing value cells with custom text (e.g., N/A or 0).
  • KEYLABEL Statement: Relabels default statistic keywords (e.g., keylabel sum="Total" mean="Average";).

6. Comprehensive Comparison of PROC REPORT & PROC TABULATE

FeaturePROC REPORTPROC TABULATE
Primary LayoutColumn-oriented listings & summariesMulti-dimensional matrix tables
Categorical Variable DeclarationDEFINE var / GROUP or ACROSSCLASS variable-list;
Analysis Variable DeclarationDEFINE var / ANALYSISVAR variable-list;
Custom CalculationsCOMPUTE ... ENDCOMPUTE blocksPre-defined statistics keywords only
Grand Totals & SubtotalsBREAK / RBREAK statementsALL keyword in TABLE expression
Test Your Knowledge

Which DEFINE statement usage type in PROC REPORT transposes the unique values of a categorical variable into horizontal column headers across the report?

A
B
C
D
Test Your Knowledge

In PROC TABULATE TABLE statement syntax, what operator is used to separate table dimensions (e.g., separating row expressions from column expressions)?

A
B
C
D
Test Your Knowledge

What is the key functional difference between the ORDER usage type and the GROUP usage type in PROC REPORT?

A
B
C
D
Test Your Knowledge

A programmer writes the following PROC TABULATE step: proc tabulate data=sashelp.shoes; class Region Product; var Sales; table Region * Product, Sales * sum; run; What does the asterisk (*) operator do between Region and Product in the row dimension?

A
B
C
D