/******************* URBAN INSTITUTE MACRO LIBRARY *********************
: Dissimilarity_index
Macro: Autocall macro to calculate the dissimilarity index between
Description
two populations.
: Open code
Use
: Peter Tatian
Author
***********************************************************************/
/***** Macro %Dissimilarity_index() - Calculates dissimilarity index *****/
Dissimilarity_index(
%macro data=, /** Input data set **/
out=, /** Output data set & var name (optional) **/
varA=, /** Population A **/
varB=, /** Population B **/
by=, /** By variable for grouping results (optional) **/
print=y /** Print results (Y/N) **/
);
/*************************** USAGE NOTES *****************************
:
SAMPLE CALLDissimilarity_index( data=Test, varA=A, varB=B, by=geo, out=Result )
%for populations A and B for units
calculates dissimilarity index
defined by var GEO, results saved to Result data set*********************************************************************/
/*************************** UPDATE NOTES ****************************
07/01/11 Peter A. Tatian
*********************************************************************/
***** ***** ***** MACRO SET UP ***** ***** *****;
%
%local input_data varDI;
%if &out = %then %do;
= _di_output;
%let out = _DI;
%let varDI
%end;%else %do;
%let varDI = %DSNameOnly( &out );
%end;
***** ***** ***** ERROR CHECKS ***** ***** *****;
%
***** ***** ***** MACRO BODY ***** ***** *****;
%
** Calculate total group A and B populations **;
%if &by ~= %then %do;
= _di_sorted;
%let input_data =&data out=&input_data;
proc sort data&by;
by
run;
%end;%else %do;
= &data;
%let input_data
%end;
=&input_data noprint nway;
proc means data%if &by ~= %then %do;
&by;
class
%end;&varA &varB;
var =_di_totals sum=&varA._s &varB._s;
output out
run;
/***
=_di_totals;
proc print data&by;
id "_di_totals";
title3
run;***/
** Merge population totals to individual unit data **;
data _di_calc;
%if &by ~= %then %do;
&input_data (keep=&by &varA &varB) _di_totals;
merge &by;
by
%end;%else %do;
&input_data (keep=&varA &varB);
set
if _n_ = 1 then set _di_totals;
%end;
** Calculate dissimilarity index formula for each unit **;
if &varA._s > 0 and &varB._s > 0 then
&varDI = 0.5 * abs( ( &varA / &varA._s ) - ( &varB / &varB._s ) );
&varDI = "Dissimilarity index of &varA vs. &varB";
label
run;
/***
=_di_calc (obs=15);
proc print data&by &varA &varB &varA._s &varB._s &varDI;
var "_di_calc";
title3
run;***/
** Sum DI for all units **;
=_di_calc noprint nway;
proc means data%if &by ~= %then %do;
&by;
class
%end;&varDI;
var =&out (drop=_type_ _freq_) sum= ;
output out
run;
%if %mparam_is_yes( &print ) %then %do;
** Print DI results **;
=&out label noobs;
proc print data%if &by ~= %then %do;
&by;
id
%end;&varDI;
var
run;
%end;
***** ***** ***** CLEAN UP ***** ***** *****;
%
** Cleanup temporary data sets **;
=work memtype=(data) nolist nowarn;
proc datasets library:;
delete _di_
quit;
%mend Dissimilarity_index;
/************************ UNCOMMENT TO TEST ***************************
** Locations of SAS autocall macro libraries **;
"K:\Metro\PTatian\UISUG\Uiautos";
filename uiautos =(uiautos sasautos);
options sasautos
options nocenter;
options mprint nosymbolgen nomlogic;
data Test;
input id geo A B;
datalines;1 1 10 20
2 1 50 0
3 1 40 40
4 1 0 20
5 2 80 40
6 2 20 90
7 2 60 50
8 2 30 0
9 2 0 0
10 2 40 60
11 3 0 50
12 3 0 70
;
run;=Test;
proc print data'Input data set: TEST';
title2
run;
title2;Dissimilarity_index( data=Test, varA=A, varB=B, by=geo, out= )
%Dissimilarity_index( data=Test, varA=A, varB=B, by=, out=work.di_out, print=n )
%File_info( data=di_out )
%/**********************************************************************/
Dissimilarity Index
Purpose: Autocall macro to calculate the dissimilarity index between two populations.