/*******************************************************************\
| Copyright (C) 2006 by SAS Institute Inc., Cary, NC, USA. |
| |
| SAS (R) is a registered trademark of SAS Institute Inc. |
| |
| SAS Institute does not assume responsibility for the accuracy of |
| any material presented in this file. |
\*******************************************************************/
/* Displaying Zipcodes on a United States Map */
/*-------------------------------------------------------------------*
* Your map may be drawn at an angle (skewed), if the range of your *
* points (to be annotated) is larger than the range of the map data.*
* This sample program demonstrates how to subset the points data set*
* so that they are within the range of the map data. This sample *
* uses the zipcode data set as the points to be annotated. *
*********************************************************************/
/*************** first reduce the dataset *************************/
proc greduce data=maps.states(drop=density) out=work.states;
id state;
run;
/******** omit Alaska Hawaii Puerto Rico and keep density lt 4 *****/
proc sql;
create table work.states as select * from work.states
where fipstate(state) not in ('AK' 'HI' 'PR')
and density < 4 /* this applies the greduce */
;
quit;
/******** get a list of the states covered in the map subset *****/
proc freq data=states noprint;
tables state/list out=stlist(keep=state);
run;
/******************************************************************
* subset the zipcode dataset to keep only the list of states *
* covered in the map dataset. this will prevent the map from *
* being skewed from outlying zipcodes *
******************************************************************/
proc sql;
create table work.zipsub as select * from sashelp.zipcode, work.stlist
where zipcode.state= stlist.state
;
run;
/*****************************************************************/
/* Create the Annotate data set, ANNO, from ZIPZUB. */
/* ANNO annotates zipcodes on the map with a '*'. */
/* sashelp.zipcode provides the x, y coordinates for the labels */
/* The labels are drawn after the map because the value of WHEN */
/* is a (after). */
/*****************************************************************/
data anno;
length style color $ 8 position $ 1 text $ 20;
retain xsys ysys '2' hsys '3' when 'a';
set work.zipsub(where=(fipstate(state) not in('HI' 'AK' 'PR')));
/* The FIPSTATE function converts the FIPS codes *
* to two-letter postal codes. */
style='marker'; text='M'; size=0.25; position='5'; color='blue';
/* convert degrees to radians */
x=-x*(atan(1)/45);
y=y*(atan(1)/45);
run;
/* combine the map and points data so they can be projected together */
data both;
set states(in=map) anno;
if map then data='M';
else data='A';
run;
proc gproject data=work.both out=work.bothprj dupok;
id state;
run;
/* split up the map and points data set */
data map anno;
set bothprj;
if data='M' then output map;
else output anno;
run;
/* Set graphics options */
filename gsasfile "C:\zipcode_usmap.gif";
goptions reset=global ftext=zapfi htext=4 gunit=pct
cback=white colors=(black) border dev=gif733 transparency
gaccess=gsasfile gsfmode=replace rotate=landscape;
;
/*****************************************************************/
/* Add titles and footnotes. */
/*****************************************************************/
title height=6 'Image After Subsetting Zipcodes';
footnote font=swissl height=2.5 justify=left ' SAS/GRAPH' move=(+0,+.5) '02'x
move=(+0,-.5) ' Software' justify=right 'US Zipcodes';
/************************************************************************/
/* Produce the map. The MAP statement includes the annotation defined */
/* in the MAPLABEL data set. DISCRETE is added so that each formatted */
/* value is treated as a separate response level. */
/************************************************************************/
proc gmap all map=map data=map anno=anno;
id state;
choro state / discrete nolegend coutline=gray;
pattern v=s r=100 c=red;
run;
quit;
|