As you indicated, a format is useful for this task:
/* use format to defgine a discrete attribute map
https://blogs.sas.com/content/iml/2019/07/15/create-discrete-heat-map-sgplot.html
<60% is red, 60-70% orange, 70-85% is yellow and over 85 is green.
*/
proc format;
value GradeFmt
0 -< .60 = "< 60%"
.60 -< .70 = "60%-69%"
.70 -< .85 = "70%-84%"
.85 - 1.00 = "85%-100%";
run;
Then you want the bar LENGTH to depend on score, but the bar COLOR to depend on the formatted category. To use both of these at once, you need a second variable for the formatted value:
data test;
format region $15. score percent6.4 range GradeFmt.;
input region score;
range = score; /* <== new variable */
datalines;
Summary .33
;
title "Example of Bar Chart";
proc sgplot data=test;
hbar region / response=score group=score;
xaxis max=1 grid; /* <== force x axis to go up to 100% */
run;
Notice, however, that if you add more students, SAS will use colors from the current ODS style. That isn't hat you want. You want to specify which colors are associated with each formatted range of grades. To specify the colors, use a discrete attribute map:
/* Create a discrete data map that assigns a color to a grade range */
/* https://blogs.sas.com/content/iml/2019/07/15/create-discrete-heat-map-sgplot.html */
/* <60% is red, 60-70% orange, 70-85% is yellow and over 85 is green. */
data GradeAttrs; /* create discrete attribute map */
length Value $11 FillColor $15;
input raw FillColor;
Value = put(raw, GradeFmt.); /* use format to assign values */
retain ID 'GradeColors' /* name of map */
Show 'AttrMap'; /* always show all groups in legend */
datalines;
0 RED
.60 ORANGE
.70 YELLOW
.85 GREEN
;
To use the map, use the DATTRMAP= option on the PROC SGPLOT statement. Also, use the ATTRID= option on the VBAR statement. Let's add a few more students (I will use NAME instead of REGION for this example) and graph the grades:
data Class;
format Name $15. score percent6.4 range GradeFmt.;
input Name score;
range = score;
datalines;
Abbott .75
Beth .59
Carol .85
Derek .61
Ed 1.0
Felix .70
Garry .71
Harry .74
Izzy .33
Jacob .84
Ken .60
Lenora .69
Mike .99
Nancy .86
;
title "Colors According to Discrete Attribute Map";
proc sgplot data=Class dattrmap=GradeAttrs;
refline .60 .70 .85 / axis=x lineattrs=(color=blue);
hbar Name / response=score group=range attrid=GradeColors;
xaxis max=1 grid;
keylegend; /* will use the order in attribute map */
run;
... View more