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

I was wondering if there is a way to use colors or something to make different groups more distinguishable in PROC PRINT. For example, the following code shows the first 100 observations, which can be grouped by Make. 

 

proc print data= sashelp.cars (obs= 100); run;

 

The first 7 have Make of "Acura" and the next 20 have Make of "Audi". Can these two groups have different colors so that they are easily distinguishable from each other? The next group is "BMW". I think "BMW" observations may have the same color as "Acura" because they are displayed next to each other.

 

I usually deal with panel data sets, so visually grouping my data when using PROC PRINT would make it a lot easier to inspect.

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Cynthia_sas
SAS Super FREQ

HI:

  I'd use a variation on that program in the paper because you can create a "counter" variable to identify the unique groups. When the counter variable is even, use one color, when the counter variable is odd use a different color:

 

alternate_colors.png

I used green and gray in honor of the nice "greenbar" paper that I used in the old mainframe printer days.

 

In order to create the counter variable (CNTMAKE), I needed for MAKE to be an ORDER usage (not the default of DISPLAY). This would have meant that MAKE would only appear on the first row of the group (such as shown in the ID example for PROC PRINT). But to have MAKE appear on every row, I created a COMPUTED item called DISPMAKE.

 

In the COMPUTE block for MAKE, I have the CALL DEFINE statement, but it needs some information. I have to find out whether this group is even or odd, based on CNTMAKE. I use the MOD function to do that. MOD divides a number and provides the remainder as a result. In this case, if the CNTMAKE number, divided by 2 is 0, that means the number is even and the row will get the green color (specified as a hex HTML color code). Otherwise, if the number is not even, it is odd, and the row will get the gray color.

 

Hope this helps explain the case.

 

Cynthia

View solution in original post

10 REPLIES 10
PaigeMiller
Diamond | Level 26

PROC PRINT has limited ability to change colors, background colors, fonts, etc. PROC PRINT does allow the BY statement to separate groups of observations, although I think the colors would not change from one BY group to another.

 

PROC REPORT will let you assign different colors to different groups of observations.

--
Paige Miller
Cynthia_sas
SAS Super FREQ

Hi:

  What color do you want to change? Background? Foreground? And, do you want to change just the cell with the value Audi or Acura? Or do you want to change the whole row? If you want to change the whole row, based on the value of the Make, then you'll need to switch to PROC REPORT instead of PROC PRINT. Look at some of the examples in this paper: http://support.sas.com/resources/papers/proceedings13/366-2013.pdf In particular, look at pages 9 and 10 if all you want to do is change the color of the Make cell. The paper has an example of coloring the Name cell.

 

  But if you want to color a whole row, then look at pages 12-14 which show coloring a whole ROW for the name='Alice'.

 

Cynthia

braam
Quartz | Level 8

Thanks! Do you suggest using PROC FORMAT and PROC REPORT together? That looks like what I'm looking for. Yes, I would like to have different colors for the whole rows of a group. 

 

But, a tricky issue is that my panel data set usually contains more than 1000 groups, so I don't think I can assign different colors to each of them using proc format. Rather, I would like to use TWO colors to make adjoining groups look distinguishable.

 

For example, Let's say that there are four groups.

 

Group 1: YELLOW

Group 2: GREY

Group 3: YELLOW

Group 4: GREY

 

Do you have any suggestion for this? Sorry for not having made my question clearer in the beginning.

ballardw
Super User

Perhaps a different procedure.

Example:

proc report data=sashelp.cars (obs=100);
   columns make model type origin drivetrain;
   define make / group;
run;
Tom
Super User Tom
Super User

You can use the ID statement with the BY statement.

proc print data= sashelp.cars (obs=10); 
  by make; 
  id make;
run;

image.png

Cynthia_sas
SAS Super FREQ

HI:

  I'd use a variation on that program in the paper because you can create a "counter" variable to identify the unique groups. When the counter variable is even, use one color, when the counter variable is odd use a different color:

 

alternate_colors.png

I used green and gray in honor of the nice "greenbar" paper that I used in the old mainframe printer days.

 

In order to create the counter variable (CNTMAKE), I needed for MAKE to be an ORDER usage (not the default of DISPLAY). This would have meant that MAKE would only appear on the first row of the group (such as shown in the ID example for PROC PRINT). But to have MAKE appear on every row, I created a COMPUTED item called DISPMAKE.

 

In the COMPUTE block for MAKE, I have the CALL DEFINE statement, but it needs some information. I have to find out whether this group is even or odd, based on CNTMAKE. I use the MOD function to do that. MOD divides a number and provides the remainder as a result. In this case, if the CNTMAKE number, divided by 2 is 0, that means the number is even and the row will get the green color (specified as a hex HTML color code). Otherwise, if the number is not even, it is odd, and the row will get the gray color.

 

Hope this helps explain the case.

 

Cynthia

braam
Quartz | Level 8

@Cynthia_sas 

Thank you so much for your awesome explanation! Following your suggestion, I made some modifications. Both work very well for me.

 


proc report data=sashelp.cars(obs=100) nowd;
	column make type model origin msrp invoice;
   compute type ;
		if make^= lag (make) then count+1;
      if mod(count,2) then do;
         call define(_row_, "style", "style=[background=lightyellow]");
      end;
   endcomp;
run;

I'm not so familar to PROC REPORT, and I would like to mimic PROC PRINT using PROC REPORT as you already know. Now I'm wondering if I really have to define all columns in PROC REPORT. If I just want to mimic PROC REPORT, do you think my code is fine? Or do I take any risk?

 

Thanks! 

Cynthia_sas
SAS Super FREQ
Hi:
I prefer NOT to use LAG in PROC REPORT. The COMPUTE BEFORE MAKE allows me to use PROC REPORTs internal "break" variable to keep track of the first of the group. Your code is less efficient because you are running the function on EVERY row. I am only executing the statements in the COMPUTE block for BEFORE 1 time for every unique group. You don't need your test on EVERY row because there's only 1 time in the group when the test will be true -- but still you are doing the test on EVERY row.

And, since I know that PROC REPORT does not have a PDV like the DATA step, I tend to avoid functions that rely on "look-back" or "look-ahead".

Cynthia
braam
Quartz | Level 8

@Cynthia_sas 

Is MAKE in "COMPUTE BEFORE MAKE" just a random choice? Thanks again.

ballardw
Super User

@braam wrote:

@Cynthia_sas 

Is MAKE in "COMPUTE BEFORE MAKE" just a random choice? Thanks again.


MAKE is your variable, so not at all random. Proc Report builds reports from left to right so to assign properties to the whole row you want to test the "left most" item to set a property for elements including that left most column.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 10 replies
  • 1896 views
  • 2 likes
  • 5 in conversation