Add a stars-style rating column to your SAS output

Now, the Star-Belly Sneetches
Had bellies with stars.
The Plain-Belly Sneetches
Had none upon thars.
- from "The Sneetches", by Dr. Seuss

Recently a user on the SAS-L mailing list had this challenge: "I would like to display stars in a table (created by PROC REPORT) based on variable values. For example, if value=3, then display five stars with 3 in yellow, and the other two in grey."

In her original post, the user had sketched out an approach that used a custom SAS format with uppercase and lowercase Xs representing the desired "star" states. It turns out that this was very close to a working approach. All she needed to do was apply the same technique that I used to add Harvey Balls to a SAS report. Like the Fix-It-Up Chappie, I'm here to offer the solution.

In my Harvey Balls example, I used ODS ESCAPECHAR and Unicode character codes to add extended characters to my SAS format labels. There is a Unicode character for a star (HEX 2605), so the same approach can work. In addition, the ESCAPECHAR sequence can set off style instructions, such as a color definition. This allows you to control the character color "mid-stream". For example, this sequence specifies a red star followed by a gray star:

~{style [color=red] ~{unicode '2605'x}} ~{style [color=ygr] ~{unicode '2605'x}}

As it happens, I keep some movie rating data that I downloaded from my Netflix account history (a very rich source of trivial SAS examples). When I apply a custom "star" format to my data, I can produce a report like this:

Here's my SAS format and the PROC PRINT code that references it. The format and report look perfect in HTML, PDF and RTF output:

/* ODS EXCAPECHAR needed to set style/unicode cues */
ods escapechar='~';

/* Captured these in macro variables for readability and */
/* easy maintenance */
%let graystar = ~{style [color=ygr] ~{unicode '2605'x}};
%let redstar = ~{style [color=red] ~{unicode '2605'x}};

/* using a 4-star system where 1 means "zero stars" */
/* and 5 means the full "4 stars" */
proc format lib=work;
value stars
1 = "&graystar.&graystar.&graystar.&graystar."
2 = "&redstar.&graystar.&graystar.&graystar."
3 = "&redstar.&redstar.&graystar.&graystar."
4 = "&redstar.&redstar.&redstar.&graystar."
5 = "&redstar.&redstar.&redstar.&redstar."
;

title "Movie titles with STARS on THARS";
proc print data=work.movies noobs;
format rating stars.;
run;

If you want to try it yourself, you can download my program with test data:

>> Complete SAS program with test data

This program should work in SAS Display Manager, SAS Enterprise Guide (select HTML output), and even SAS Studio via SAS OnDemand for Academics.