BookmarkSubscribeRSS Feed
CharleneW
Calcite | Level 5
Hi -

I have a question on legend and pattern with PROC GMAP. Below is my code.

**************************************
proc format;
value color
0 = "No Patients"
1-5 = "1-5 Patients"
6-10 = "6-10 Patients"
11-20 = "11-20 Patients"
21-high = ">20 Patients"
;
run;

legend1 origin=(2,70)pct mode=share across=1 shape=bar(2,2) value=(height=1.5);

pattern1 v=ms c=white;
pattern2 v=ms c=grayca;
pattern3 v=ms c=yellow;
pattern4 v=ms c=orange;
pattern5 v=ms c=red;

proc gmap map=edmap.nys_zip_utm data=d&datarange all annotate=countyline;
id zip;
choro sum&i /discrete legend=legend1 coutline=black cempty=black;
format sum&i color.;
run;

**************************************************

Ideally, the map shows 5 colors (using defined 5 patterns) and the legend shows 5 categories. Hower, the problem is that whenever the dataset does not have the value for a category in "sum&i" (e.g., variable "sum&i" contains no values of 0) , the legend will only show 4 categories instead of 5, and the colors will also be wrong (e.g., category "1-5 Patients" will then be mapped white instead of grayca).

Does anybody know how to show all categories in the legend even if the data set does not have all category values? Thanks!
2 REPLIES 2
GraphGuy
Meteorite | Level 14
In situations with discrete values, I'd recommend specifying the values you want in the legend via the "midpoints=" in gmap. But in this case where you have "ranges" of values that are being mapped into discrete bins using user-defined formats, I'm not sure that's possible.

But a sure-fire way to get what you're wanting is to insert "fake" values into the data - 1 value in each of the possible ranges. And by "fake", I mean assign them to a map area that doesn't actually exist in the geographical map (I like to use a map id of '.' (missing)).

Here is an example - the first map's data doesn't cover all the ranges in the user-defined format, and the 2nd map (with the addition of 'fake' data) does...

proc format;
value color
0 = "No Patients"
1-5 = "1-5 Patients"
6-10 = "6-10 Patients"
11-20 = "11-20 Patients"
21-high = ">20 Patients"
;
run;
pattern1 v=ms c=white;
pattern2 v=ms c=grayca;
pattern3 v=ms c=yellow;
pattern4 v=ms c=orange;
pattern5 v=ms c=red;
legend1 label=none across=1 position=(right middle);

proc sql;
create table real_data as select unique state, (round(ranuni(335)*50))+5 as my_value
from maps.us;
quit; run;

title "Data doesn't cover all possible ranges";
proc gmap data=real_data map=maps.us;
format my_value color.;
id state;
choro my_value / discrete legend=legend1;
run;

data fake_data;
state=.;
my_value=0; output;
my_value=1; output;
my_value=6; output;
my_value=11; output;
my_value=21; output;
run;
data mod_data; set real_data fake_data;
run;

title "Modified data covers all possible ranges";
proc gmap data=mod_data map=maps.us;
format my_value color.;
id state;
choro my_value / discrete legend=legend1;
run;
CharleneW
Calcite | Level 5
Thanks Robert! It worked!

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 2 replies
  • 1326 views
  • 1 like
  • 2 in conversation