ROC Curve Analysis using PROC LOGISTIC

/*ROC Curve Analysis Macro*/

/*a hypothetical data set*/
data asdf;set sashelp.class;
EVENT=0;
if Weight > 100 then EVENT=1;
PREDICTOR=height;
run;

/*data name*/
%let dataname=asdf;
%let outcome=EVENT;
%let ind=PREDICTOR;
%let save_graphic=C:\Documents and Settings\19702\My Documents\sas;

ods html PATH="&save_graphic" (url=none) file="&dataname &ind .html";
ods graphics on / imagename="&dataname&ind";
proc logistic data=&dataname descending OUTEST=&dataname.result;
title "&dataname";
model &outcome =
&ind
/ outroc=&dataname.kaz2 ROCEPS=0 ;
output out = m2 p = prob xbeta = logit ;
ods output ParameterEstimates=kazcoeff
Association=kazassoc
ConvergenceStatus=kazconverg(keep= reason);
run;
ods graphics off;
ods html close;

proc transpose data=kazassoc out=T1;
var cValue1;
id label1;
run;
proc transpose data=kazassoc out=T2;
var cValue2;
id label2;
run;

data kazassoc2;
merge T1 T2;
run;

/*ods trace off;*/
/*Get descriptive statistics*/

ods listing close;
proc means data=&dataname;
var
&outcome
&ind
;
ods output summary=uekawa;
run;
ods listing;
/*get significance of the independent varible*/
data kazcoeff2;
set kazcoeff;
if Variable="&ind";
keep ProbChiSq StdErr flag;
flag=1;
label ProbChiSq="P-value for the ind var effect";
label StdErr="Stderr for the ind var effect";
run;

data &dataname.kaz2;set &dataname.kaz2;
flag=1;
run;

data &dataname.result;
set &dataname.result;
flag=1;
run;

data &dataname.kaz3;merge &dataname.kaz2 &dataname.result kazcoeff2;
by flag;
run;

data &dataname.kaz4;set &dataname.kaz3;
Distance=sqrt( (0-_1MSPEC_)**2 + (1-_SENSIT_)**2 );
suji=_n_;
run;
proc sql;
create table &dataname.kaz5 as
select *,
min(distance) as minimum_distance
from &dataname.kaz4;
run;

data optimal;
retain CUT_OFF_VALUE;
set &dataname.kaz5;
CUTOFF=0;
if distance = minimum_distance then do; CUTOFF=1; type="Dist to perfection";end;
/*if distance2 = maximum_distance2 then do; CUTOFF=1;
type="Dist to noninf";end;*/
if cutoff=1;
effect=&ind ;
LOGIT=LOG(_PROB_ / (1-_PROB_));
CUT_OFF_VALUE=((LOGIT-Intercept)/effect);
drop cutoff ;
run;
data results_of_ROC;
merge optimal uekawa kazassoc2 kazconverg;

TRUE_POSITIVE_RATE=_SENSIT_;
TRUE_NEGATIVE_RATE=1-_1MSPEC_;
AUC=C;
run;

proc print data=results_of_ROC;
title "ROC stats for &outcome";
var CUT_OFF_VALUE
TRUE_POSITIVE_RATE
TRUE_NEGATIVE_RATE
AUC ;
run;