BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
KonstantinVasil
Obsidian | Level 7

I am trying to get familiar with Proc Report but many of the articles and examples are very sophisticated. In my case I am only concerned with the formatting of the output and not in summary statistics and etc.

 

I have a 2 variables table with 10 rows. Then I want to report the table into 2 sections divided by spanning headers. Example report:

<Main header - spanning over 2 columns>

<empty spacing header - spanning over 2 columns>

 

<Section header1 - spanning over 2 columns>

<Data - rows 1-5, no variables names>

 

<Section header2 - spanning over 2 columns>

<Data - rows 6-10, no variables names>

 

Can this be achieved with a single table or the table should be divided to 2 tables? If yes could you provide some examples?

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

Hi:

  One of the great benefits of the COMPUTE block is the ability to use conditional logic. If you modified your COMPUTE block to test for the value of GRP, then you'd be able to do this:

conditional_line.png

Cynthia

View solution in original post

11 REPLIES 11
Ksharp
Super User
data have;
set sashelp.class;
if _n_ in (1:9) then group=1;
 else group=2;
run;

proc report data=have nowd;
column group name age;
define group/order noprint;
compute name;
n+1;
endcomp;
compute before group;
line ' ';
line ' ';
line @1 '_Name' @10 '_Age';
endcomp;
run;
KonstantinVasil
Obsidian | Level 7
Thank you. How can I add the empty heading after each group heading? Also how can I set different headings for each group?
Cynthia_sas
SAS Super FREQ

Hi:

 

  This is the output you get from using the LINE statement in the above example:

orig_example.png

  I thought the requirement was for NO variable names above each group/sub-group. At any rate, the basic idea in this example is one way to approach your desired output. Making some "helper" variables that can be used for break processing will allow you to divide the output rows without needing a second table. (and using line pointer controls like @1 and @10 doesn't look very good in HTML output -- might work better in LISTING).  Here's a slightly different variation on the same general approach. There are 3 different places (to start) where you can impact this output to get spanning headers -- the COLUMN statement (#1), a COMPUTE BEFORE (#2) with a LINE statement or a COMPUTE AFTER (#3) .revised_example.png  This paper shows more places where you can impact the output with a LINE statement and discusses BREAK processing in PROC REPORT: https://support.sas.com/resources/papers/proceedings17/SAS0431-2017.pdf .Hope this helps,Cynthia

KonstantinVasil
Obsidian | Level 7

Great, but how can I specify the group header to be different depending on the group number?

Cynthia_sas
SAS Super FREQ

Hi:

  One of the great benefits of the COMPUTE block is the ability to use conditional logic. If you modified your COMPUTE block to test for the value of GRP, then you'd be able to do this:

conditional_line.png

Cynthia

KonstantinVasil
Obsidian | Level 7

Thank you. For some reason the length of brkline gets cut at 18 characters. I've tried setting different width options without success. Any idea what may be limiting that? Also is there a ways to set only the style of a particular to Header?

Cynthia_sas
SAS Super FREQ

Hi:
Sorry, without data and your actual code, it is impossible to say why the length might not be what you expect.

I don't know what you mean when you ask "set only the style of a particular to Header" -- of a particular WHAT? A data cell, a word in the Header. If you want to conditionally change the style of the line you write, then you need to look at using other techniques.

As you can see in my example, the BRKLINE variable can be quite long without being truncated. Using ODS ESCAPECHAR allows me to change the font characteristics. Overrides to the LINES style (where I have changed the background to a different color) will apply to ALL the output from ALL the LINES statements, as shown below:
change_style.png

I really recommend that you read about PROC REPORT and work on understanding how to use it. We teach these ODS STYLE concepts in our Report Writing 1 class, but there are LOTS of papers and references on the web about PROC REPORT.

Cynthia

KonstantinVasil
Obsidian | Level 7

 

Here is an example that displays the behaviour of cutting the text in the headers. It is very hard for me to find what is limiting the text in the lines:

data newclass; set sashelp.class;
	if _n_ in (1:3) then group=1;
	else if _n_ in (4:5) then group=2;
	else group=3;
run;
proc report data=newclass nowd;
	column group ('Segment Information' name age);
	define name / display ' '; 
	define age / display ' '; 
	define group/order noprint;

compute before group;
		if group = 1 then do; brkline = 'Rating Methodology'; brkline2=''; end;
		else if group = 2 then do; brkline = 'Latest Recalibration'; brkline2=''; end;
		else if group = 3 then do; brkline = 'Rating Distribution <date>'; brkline2='Rating Class Level Analysis'; end;
		line ' ';
		line brkline2 $varying100.;
		line brkline $varying100.;
	endcomp;
run;
Cynthia_sas
SAS Super FREQ
Hi:
Did you notice that my last example had a LENGTH statement? The same thing would happen to you in a DATA step program. This is why you need a LENGTH statement. The first reference to a variable, whether in a DATA step or a COMPUTE block sets the length or size of the variable. Count the characters in the string "Rating Methodology". The fix is the same for PROC REPORT as for a DATA step -- use a LENGTH statement for your BRKLINE variable inside the COMPUTE block.

Cynthia
KonstantinVasil
Obsidian | Level 7

 

Dear Cynthia, thank you for all of the help. However, using ODS Excel, when I experiment with adding one additional blank line, it appears as a new line in the same row, while I need it to be a new blank row.

 

 

compute before grp;
   if grp = 1 then brkline = "line1";
   else if grp = 2 then brkline = "line2";
   line brkline $varying100.; 
   line ''; /* How to make this line to appear in a new blank row??? */
endcomp;

 

 

Cynthia_sas
SAS Super FREQ

Hi:

  You'll need to make another helper variable for breaking. Everything within that single COMPUTE block is written to one cell, which is on one row.

  Something like this. See the helper variable "extra_brk" that I put into the data.

ods_excel_make_row.png

Hope this helps,

Cynthia

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 3503 views
  • 4 likes
  • 3 in conversation