BookmarkSubscribeRSS Feed
Quodly
Obsidian | Level 7

hi,

 

i've posted this question before but it somehow disappeared after i edited it.

 

i want to change the statistic in the ROC curve plot of proc logistic:

 

data have;
  input pred resp;
  datalines;
0 1
1 1
2 0
3 1
4 1
5 1
6 1
7 0
8 0
9 1
;

ods graphics on;
                
ods select roccurve;

ods noproctitle;
   
proc logistic;
  model resp = pred / nofit;
  roc "have" pred = pred;  
run;

ods graphics off;

instead of the c statistic (AUC, AUROC), i want to display Somers' d statistic (Gini coefficient, AR). both statistics are related by:

 

 

d = 2*c-1.

 

i use proc template with the source statement to get the following code, where i've changed only a single line (see comment on the right side):

 

proc template;
  define statgraph Stat.Logistic.Graphics.Roc;
     notes "Receiver Operating Characteristic Curve";
     dynamic _cValue _TITLE _ROCID _ROCIDNOTE _byline_ _bytitle_ _byfootnote_;
     mvar _ROC_YAXISOPTS_LABEL _ROC_XAXISOPTS_LABEL _ROC_ENTRYTITLE _ROC_ENTRYTITLE2 _ROC_ENTRY_ID;
     BeginGraph / designwidth=defaultDesignHeight;
        if (EXISTS(_ROC_ENTRYTITLE))
           entrytitle _ROC_ENTRYTITLE;
        else
           entrytitle _TITLE;
        endif;
        if (EXISTS(_ROC_ENTRYTITLE2))
           entrytitle _ROC_ENTRYTITLE2 / textattrs=GRAPHVALUETEXT;
        else
           entrytitle "Gini coefficient = " eval (STRIP(PUT(2*_CVALUE-1,6.4))) / textattrs=GRAPHVALUETEXT; /* i've changed only this line */
        endif;
        layout overlayequated / equatetype=square yaxisopts=(gridDisplay=auto_on label=_ROC_YAXISOPTS_LABEL shortlabel="TPF"
           offsetmin=0.05 offsetmax=0.05) xaxisopts=(gridDisplay=auto_on label=_ROC_XAXISOPTS_LABEL shortlabel="FPF" offsetmin=0.05
           offsetmax=0.05) commonaxisopts=(tickvaluelist=(0 .25 .5 .75 1) viewmin=0 viewmax=1);
           lineparm x=0 y=0 slope=1 / clip=true extend=true lineattrs=GRAPHREFERENCE;
           seriesplot y=_SENSIT_ x=_1MSPEC_ / primary=true rolename=(tip1=_ROC_ tip2=_FREQ_ tip3=_WEIGHT_ tip4=_POSPRED_ tip5=
              _NEGPRED_ tip6=_PROB_) tip=(tip1 y x tip2 tip3 tip4 tip5 tip6);
           if (EXISTS(_ROCID))
              scatterplot y=_SENSIT_ x=_1MSPEC_ / rolename=(tip1=_ROC_ tip2=_FREQ_ tip3=_WEIGHT_ tip4=_POSPRED_ tip5=_NEGPRED_ tip6=
                 _PROB_ tip7=_ROCID) tip=(tip1 tip7 y x tip2 tip3 tip4 tip5 tip6) freq=eval (1-MISSING(_ROCID));
           endif;
           seriesplot y=_SENSIT_ x=_1MSPEC_ / datalabel=_ROCID datalabelattrs=GRAPHDATADEFAULT lineattrs=GRAPHDATADEFAULT (thickness=
              0) markerattrs=GRAPHDATADEFAULT (size=0) rolename=(tip1=_ROC_ tip2=_FREQ_ tip3=_WEIGHT_ tip4=_POSPRED_ tip5=_NEGPRED_
              tip6=_PROB_) tip=(tip1 y x tip2 tip3 tip4 tip5 tip6);
           if (EXISTS(_ROC_ENTRY_ID))
              entry halign=right textattrs=GRAPHDATATEXT _ROC_ENTRY_ID / location=inside editable=true valign=bottom;
           else
              entry halign=right textattrs=GRAPHDATATEXT _ROCIDNOTE / location=inside editable=true valign=bottom;
           endif;
        endlayout;
        if (_BYTITLE_)
           entrytitle _BYLINE_ / textattrs=GRAPHVALUETEXT;
        else
           if (_BYFOOTNOTE_)
              entryfootnote halign=left _BYLINE_;
           endif;
        endif;
     EndGraph;
  end;
run;

 

rerunning proc logistic gives what i want.

 

for two predictors, i want to do the same:

 

data have;
  input pred1 pred2 resp;
  datalines;
0 0 1
2 1 1
2 2 0
4 3 1
2 4 1
5 5 1
7 6 1
9 7 0
9 8 0
7 9 1
;
    
ods graphics on;

ods select rocoverlay;

ods noproctitle;
   
proc logistic;
  model resp = pred1 pred2 / nofit;
  roc "pred1" pred = pred1;  
  roc "pred2" pred = pred2;

  roccontrast reference("pred1");
run;

ods graphics off;
proc template;
  define statgraph Stat.Logistic.Graphics.ROCOverlay;
     notes "Receiver Operating Characteristic Overlaid Curves";
     dynamic _TITLE _byline_ _bytitle_ _byfootnote_;
     mvar _ROC_YAXISOPTS_LABEL _ROC_XAXISOPTS_LABEL _ROCOVERLAY_ENTRYTITLE;
     BeginGraph / designwidth=defaultDesignHeight;
        if (EXISTS(_ROCOVERLAY_ENTRYTITLE))
           entrytitle _ROCOVERLAY_ENTRYTITLE;
        else
           entrytitle _TITLE;
        endif;
        layout overlayequated / equatetype=square yaxisopts=(gridDisplay=auto_on label=_ROC_YAXISOPTS_LABEL shortlabel="TPF"
           offsetmin=0.05 offsetmax=0.05) xaxisopts=(gridDisplay=auto_on label=_ROC_XAXISOPTS_LABEL shortlabel="FPF" offsetmin=0.05
           offsetmax=0.05) commonaxisopts=(tickvaluelist=(0 .25 .5 .75 1) viewmin=0 viewmax=1);
           lineparm x=0 y=0 slope=1 / clip=true extend=true lineattrs=GRAPHREFERENCE;
           seriesplot y=_SENSIT_ x=_1MSPEC_ / tip=(group y x) group=_ROC_ index=_GROUP_ name="Step" primary=true;
           discretelegend "Step" / title="Gini coefficient"; /* i've changed only this line */
        endlayout;
        if (_BYTITLE_)
           entrytitle _BYLINE_ / textattrs=GRAPHVALUETEXT;
        else
           if (_BYFOOTNOTE_)
              entryfootnote halign=left _BYLINE_;
           endif;
        endif;
     EndGraph;
  end;
run;

here, i can only change the title of the legend - but i don't know from where the c statistic in parentheses comes?

 

is it possible to change that, too?

 

any help is much appreciated.

 

2 REPLIES 2
Ksharp
Super User
data have;
  input pred resp;
  datalines;
0 1
1 1
2 0
3 1
4 1
5 1
6 1
7 0
8 0
9 1
;

  
ods select none;
ods output Association=Association;
proc logistic data=have;
  model resp = pred /  outroc=roc;
run;
ods select all;

proc sql noprint;
select cValue2 into :Gamma from Association where Label2='Gamma';
select cValue2 into :c from Association where Label2='c';
quit;


proc sgplot data=roc aspect=1 noautolegend;
lineparm x=0 y=0 slope=1/lineattrs=(color=grey);
series x=_1MSPEC_ y=_SENSIT_;
inset "ROC = &c" "Gamma = &Gamma"/position=topleft;
xaxis grid;
yaxis grid;
run;
Quodly
Obsidian | Level 7

thank you for your workaround - but i'd prefer an answer which adjusts the graph template.

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 1329 views
  • 2 likes
  • 2 in conversation