*
; options nosource; /* A - CALCULATES AREAS AND MAIN POINTS FROM MAP DATA SETS, IN UNITS OF LONGITUDE/LATITUDE COORDINATES Written: July 19, 1993 Developed using SAS 6.07 on VM/CMS and SAS 6.04 on DOS PC Author: Arnold Schick Procs: - Other: SAS MACRO language Macros: only A Note: Do not use _AREA_ as a data set name, this data set contains the results and is new created by every run. Please be sure, some map datasets use ID instead of SEGMENT and vice versa, or STATE as ID. Macro Call: %A(DATA,X,Y,ID,SEGMENT,XSCALE,YSCALE); MACRO VARIABLE DESCRIPTION ------------------+------------------------------------------------- In Request: DATA Name of SAS data set with input data. If this parameter is missing or blank _LAST_ is used. X Variblename of latitude in input SAS MAP data data set. If missing or blank, X is used. Y Variablename of longitude in input SAS MAP data If missing or blank, Y is used. ID Variablname of id SAS MAP data set variable. If missing or blank, ID is used. SEGMENT Variablename of segment SAS MAP data set variable. If blank or missing, SEGMENT is used. If not in input data set, SEGMENT is set to missing. XSCALE Value of scaling-factor for latitude-values. If missing or blank, 1.0 is used. XSCALE <> 0 ! YSCALE Value of scaling-factor for longitude-values. If missing or blank, 1.0 is used. YSCALE <> 0 ! Examples: *%macro A (data, x,y,id,segment,1,1); %A (maps.us , x,y,state,segment,1,1); %A (maps.germany); Reference: For more information: Arnold Schick University of Marburg Academic Computing Center Hans-Meerwein-Str. 3550 Marburg/Lahn Germany Internet: schick@hrz.uni-marburg.de If you find an error-condition (it is provided 'as it is') please let me know about this error-condition. And when you have good tips for better formulation with SAS, let me also know. Please acknowledge the author as the provider of this method in publications that it used. Thank you very much. */ %macro A (data,x,y,id,segment,xscale,yscale); options nosource nostimer nosymbolgen nonotes; %if &data = or &data = . %then %let data = _LAST_ ; %if &x = or &x = . %then %let x = x; %if &y = or &y = . %then %let y = y; %if &id = or &id = . %then %let id = id; %if &segment = or &segment = . %then %let segment = segment; %if %str(&xscale) = %str(0) or %str(&yscale) = %str(0) %then %goto quit_1; data _NULL_; xs = symget('xscale') / 1 ; if xs = . then xs = 1; call symput('xscale',xs); ys = symget('yscale') / 1 ; if ys = . then ys = 1; call symput('yscale',ys); run; data _area_ (rename=(id_previ=&id seg_prev=&segment) keep=id_previ id_face seg_prev seg_face ax ay) a (keep= ax ay adx ady); set &data end=last; retain id_face 0 face 0 seg_face 0 y_sourc2 isle 1 adx 0 ady 0 ax 0 ay 0; &x = &x*&xscale; &y = &y*&yscale; x_previo = lag(&x); y_previo = lag(&y); id_previ = lag(&id); seg_prev = lag(&segment); xm=(&x-x_previo)/2 + x_previo; if &x = . then do; seg_face + isle*abs(face); ax + isle*abs(adx); ay + isle*abs(ady); y_sourc2 = 0; face = 0; isle = -1; adx = 0; ady = 0; end; else y_sourc2 = (xm-x_previo)*y_previo + (&x-xm)*&y; if ((id_previ ^= &id) or (&segment ^= seg_prev)) and _N_ > 1 then do; seg_face + isle*abs(face); seg_face = abs(seg_face); id_face + seg_face; ax + isle*abs(adx); ay + isle*abs(ady); output a; ax = ax/id_face; ay = ay/id_face; output a; output _area_; if &id ^= id_previ then id_face = 0; isle = 1; face = 0; seg_face = 0; adx = 0; ax = 0; ady = 0; ay = 0; end; else if &x ^= . then if &x > x_previo then do; face + -abs(y_sourc2); adx + -abs(y_sourc2)*xm; ady + -abs(y_sourc2)*y_sourc2/(2*(&x-x_previo)); * output a; end; else if &x=x_previo then do; * output a; end; else do; face + abs(y_sourc2); adx + abs(y_sourc2)*xm; ady + abs(y_sourc2)*y_sourc2/(2*(&x-x_previo)); * output a; end; if last then do; seg_face + isle*abs(face); seg_face = abs(seg_face); id_face + seg_face; ax + isle*abs(adx); ay + isle*abs(ady); output a; ax = ax/id_face; ay = ay/id_face; output a; output _area_; end; run; options notes; data _area_; set _area_; run; options nonotes; %goto final; %quit_1 : %put MACRO-HALT: Scaling-factor(s) equal 0 ; %final : ; options source stimer notes; %mend A; options source; *Example; /* *libname in 'c:\d\sas\maps'; data one; set in.brdlan; *where id in (1 6 8 11); *selects wanted regions; run; %a(one,x,y,id,segment); proc sort data=_area_ out=_area_; by id segment; run; data _area_ ; set _area_ ; keep id id_face seg_face ax ay; if last.id or last.segment then output; by id segment; run; proc print data=_area_; run; *calculates mainpoint of all areas; data sum (keep=summa px py); set _area_ end=last; summa + id_face; px + id_face * ax; py + id_face * ay; if last then do; px=px/summa; py=py/summa; output; end; run; proc print data=sum; run; *End of Example; */ *;