Pages

SyntaxHighlighter

Monday, August 18, 2014

Put it on the Map

There is a major benefit in visually displaying data on maps as it is easier to consume the information. The below program creates sample data for 16 states using their numeric FIPS codes then PROC GMAP to render the content.

The custom %mapanno macro uses the MAPS.USCENTER data set to locate the center of each state and place its data value (if found) below it. The mapanno data set uses the postion= annotate variable to place the values on the map. The next image displays the location for select position= values.

However, that technique does not work well for some coastal states on the eastern seaboard. Those states contain an ocean = 'Y' column value and in those cases, the state abbreviation is shown followed by a slash (/) and its value.

There was still an issue when displaying the value for Massachusetts (MA) as its value was being truncated. The solution was to utilize a technique from SAS/Graph expert, Robert Allison's samples where he uses title5 a=-90 h=6pct " "; to provide some extra space for those values. Here is the finished result:

data sample ;
  format value comma9. ;
  do state = 6, 13, 17, 20, 23, 24, 25, 26, 28, 34, 36, 37, 48, 49, 53, 56 ;
    value = int( ranuni( 1 ) * 10000 ) ;
    output ;
  end ;
run ;

%macro mapanno( dsn =, mapvar=, textsize = 1.5 ) ;
  data mapanno ;
    length function $8 text $20 size 8 ;
    retain xsys ysys '2' hsys '3' when 'a' style "'Albany AMT'" ;

    merge &dsn.( keep = state &mapvar. in = xm ) maps.uscenter ;
      by state ;
    where fipstate( state ) not in( 'AK', 'DC', 'HI', 'PR' ) ;
    lagocean = lag( ocean ) ;
    size = &textsize. ;

    if ocean = 'Y' then do ;
      if not missing( &mapvar. ) then text = catx( " / ", fipstate( state )
        , ifc( vtype( &mapvar ) = 'C', &mapvar.
          , strip( putn( &mapvar., vformat( &mapvar. ) ) ) ) ) ;
      else text = fipstate( state ) ;
      function = 'label' ;
      position = '6' ;
      output ;
      function = 'move' ;
      output ;
    end ;

    position = '5' ;
    if ocean = 'N' then do ;
      if lagocean = 'Y' then do ;
        function = 'draw' ;
        size = &textsize / 4 ;
      end ;
      else do ;
        function = 'label' ;
        if not missing( &mapvar ) then do ;
          position = '2' ;
          text = fipstate( state ) ;
          output ;
          position = '5' ;
          text = ifc( vtype( &mapvar. ) = 'C', &mapvar.
            , strip( putn( &mapvar., vformat( &mapvar. ) ) ) ) ;
        end ;
        else text = fipstate( state ) ;
      end ;
      output ;
    end ;
  run ;
%mend ;
%mapanno( dsn = sample, mapvar = value )

goptions reset = pattern ;
pattern1 v = s c = cxff0000 ;
pattern2 v = s c = cxffa500 ;
pattern3 v = s c = cxffff00 ;
pattern4 v = s c = cx008000 ;
pattern5 v = s c = cx0000ff ;

ods listing close ;
ods html path = "c:\temp\" body = "anno.html" ;
  title "Sample Random Data" ;
  title5 a=-90 h=6pct "  " ;

  proc gmap
      data = sample
      map  = maps.us
      anno = mapanno 
      all ;
         id state ;
   where fipstate( state ) not in( 'AK', 'DC', 'HI', 'PR' ) ;
   choro value / levels = 5 ;
  run ;
  quit ;
ods html close ;
ods listing ;