Maps Online >Resources SAS logo
Feedback   

Sample Data
Sample Programs
Tools
Useful Links

/*******************************************************************\
| 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;