如何在proc gmap中为美国东北部州添加非重叠标签?

时间:2018-04-09 14:33:28

标签: sas label

我试图在美国地图上绘制两个变量。我想在括号内显示产品A的价格和它下面的差异v / s产品B.代码几乎完成了。我面临的唯一问题是,我无法为像新泽西州,佛蒙特州和汉普郡这样的东北小州贴标签而没有重叠。我想要一些类似附件的文件,其中上述状态'标签用一条线显示。

以下是我到目前为止的代码。

proc import datafile="../Book8.csv" out=response dbms=csv replace;
run;

proc export data=response outfile="check.csv" dbms=csv replace;
run;

proc sort data=response out=sallx2(drop=Price_B); by STATECODE; run;
proc sort data=maps.us2 out=sus2(keep=STATE STATECODE); by STATECODE; run;

data mapfips;
merge sallx2 (in=a)
sus2 (in=b)
;
by STATECODE;
if a;
run;

data mapfips;
set mapfips;
dummy="$";
dummy1="(";
dummy2=")";
new_Price_A=catx("", of dummy Price_A);
new_Difference=catx("", of dummy1 dummy Difference dummy2);
run;


proc sort data=mapfips out=smapfips; by STATE; run;
proc sort data=maps.uscenter out=suscenter(keep=STATE X Y) nodupkey;
by STATE; run;
data mapfips2;
merge smapfips (in=a)
suscenter (in=b)
;
by STATE;
if a;
run;

data stlabel;
length function $ 8 position $ 1
text $ 20 style $ 30;
set mapfips2;
retain flag 0
xsys ysys '2'
hsys '3' when 'a';
format Difference dollar5.2;
text=new_Difference; style="'Albany AMT'";
color='black'; size=2; position='7'; output;
format Price_A dollar5.2;
text=new_Price_A; style="'Albany AMT'";
color='black'; size=2; position='4'; output;
if ocean='Y' then do;
text=new_Difference; position='6'; output;
function='move';
flag=1;
end;
else if flag=1 then do;
function='draw'; size=2; output;
flag=0; 
end;
output; 
run;

proc contents data=stlabel; 
run;

proc format;
picture Difference_
low - -0.01  = 'negative'
0.00 = 'parity'
0.01 -high = 'positive'
;    
run;

proc contents data=response;

pattern1 color=green;
pattern2 color=yellow;
pattern3 color= red;


title 'PRODUCT A V/S PRODUCT B';


proc gmap
data=response
map=maps.us
all;
id STATECODE;
format Difference Difference_.;
choro Difference / discrete annotate=stlabel ;
run;
quit;

enter image description here

1 个答案:

答案 0 :(得分:1)

爬完:

您需要了解“注释变量”和“注释函数”,以及Maps.USCENTER

此代码是SAS示例“示例6:在美国地图上标记状态”的修改。代码比示例更冗长,用于解释,并且由于每个状态有两个标签行和调出调整。

USCENTER数据有一个特殊功能:

  • Ocean变量,当Y(是)时,状态会有两行
    • 第一行是'safe` X& Y为文本,偏移来自州实际地理中心。用于放置标注和呼出线的起点。
    • 第二行是X& Y表示实际的地理中心和呼出线的终点。

代码具有功能

  • Flag变量,保留以跟踪行是否为海洋状态调用行的后续行,因此该函数应设置为'draw'
  • 调整特定状态以更改SAS提供的标注坐标为if state2 = 'VT' then do; * tweak first end-point of call out for VT; x = 0.27; y = 0.20; position1 = 'A'; /* RAD: right aligned 1/2 cell above **/ position2 = 'D'; /* RAD: right aligned 1/2 cell below **/ end;

代码不会创建之前不存在的新标注。 您必须在maps.uscenters数据的副本中添加行才能创建新的标注。

/* Original from SAS Example 6: Labeling the States on a U.S. Map */

goptions reset=global gunit=pct border cback=white
         colors=(black blue green red)
         ftext='Albany AMT'  /* RAD: Change default font to 'Albany AMT' */
         htitle=6 htext=3
;

data WORK.myTexts;
  set maps.uscenter;
  by state;
  if first.state;
  line1 = 'Line 1';
  line2 = 'Line 2';

  state2 = fipstate(state);
  if state2 ne 'DC';
run;

data WORK.map_annotation; /* RAD: use WORK libref instead of REFLIB */
   length function $ 8 x y 8 position $1 text $20;
   retain 
    flag 0 
    xsys ysys '2' /* RAD: coordinate system for drawing, 2 means data values */
    hsys '3'  /* RAD: coordinate system for heights, 3 means % of graphics output area */
    when 'a'  /* RAD: annotation occurs after all procedure drawing is done */
    style "'Albany AMT'"  /* RAD: quoted style value indicates a true type font is being requested for drawn labels */
   ;
   merge
      myTexts (in=myAnno)
      maps.uscenter (drop=long lat)
  ;

  by state;
  if myAnno;

   function='label';
   size=1.5; /* RAD: size for label is font height in HSYS coordinate system, make it small enough for stacking two labels */
   position='B'; /* RAD: text position is centered about X and Y at half cell above Y */

   if ocean='Y' then do;

         position1 = 'C'; /* RAD: left aligned 1/2 cell above */
         position2 = 'F'; /* RAD: left aligned 1/2 cell below */

         if state2 = 'VT' then do;
           * tweak first end-point of call out for VT;
           x = 0.27;
           y = 0.20;
           position1 = 'A'; /* RAD: right aligned 1/2 cell above */
           position2 = 'D'; /* RAD: right aligned 1/2 cell below */
         end;

         text=catx(':', state2, line1); 
         position=position1;
         output;

         text=line2;
         position=position2;  
         output;

         function='move'; /* RAD: move the pen to the start of call-out line */
         flag=1;
         output;
   end;
   else if flag=1 then do;
         /* Dealing with an Ocean state,
          * this is the second observation for it (data feature of MAPS.USCENTER) 
          */
         function='draw'; /* RAD: draw line to the end of the call-out line (which is state geo-center) */
         size=.25; /* Size for 'draw' is line thickness */
         flag=0;
         output;
   end;
   else do;
         /* USCENTER row is neither ocean state, nor ocean state 2nd row */
         /* Thus a state is one without a call-out line
          * place the annotation at the states center */
         text=line1;
         position='B';  /* RAD: Center aligned 1/2 cell above */
         output;
         text=line2;
         position='E';  /* RAD: Center aligned 1/2 cell above */
         output;
   end;
run;

title 'Positioning State Labels with MAPS.USCENTER';
footnote j=r 'GR19N06 ';

pattern1 value=mempty color=blue repeat=50;

proc gmap data=maps.us map=maps.us;
   id state;
   choro state / nolegend
                 annotate=WORK.map_annotation;
run;
quit;