/**************************************** * This program requires SAS9.4 M1. *****************************************/ %let nVars=5; /* Number of variables */ %let varList = msrp mpg_city length horsepower weight; %let nTop=12; /* Top N */ proc sort data=sashelp.cars out=cars_msrp (keep = &varList. model make ); by descending msrp; run; /* Get Max */ proc means data=cars_msrp ( obs=&nTop. ) noprint ; var &varList; output out=cars_max max=max1-max&nVars. ; run; /* Normalize the values to [0, 1] by dividing with their max */ data cars_norm; drop idx _type_ _freq_ max1 - max&nVars. ; array max_tmp[&nVars.] _temporary_ ; /* _temp_ for retaining maxs */ if _n_ = 1 then do; /* Initialze the maximums */ set cars_max; array max[&nVars]; do idx = 1 to &nVars; max_tmp[idx] = max[idx]; end; end; else do; set cars_msrp (obs = &nTop.); array values[*] &varList; array norms[*] norm1 - norm&nVars. ; do idx=1 to dim(values); norms[idx] = values[idx] / max_tmp[idx]; end; output; end; run; /* proc print data=cars_norm; run; */ data radarPoly; set cars_norm; array values[*] &varList.; array norms[*] norm1 - norm&nVars. ; array varNames[&nVars] $32 _temporary_ ("MSRP" "MPG City" "Engine Size" "Horsepower" "Weight"); array axisLabels[&nVars] $1 _temporary_ ("$" "M" "L" "H" "W"); drop deg2Rad angleIncr startAngle idx angleRads xComp yComp; retain deg2Rad angleIncr startAngle; if _n_ = 1 then do; deg2Rad = atan(1)/45; angleIncr = 360 * deg2Rad / &nVars; startAngle = 90 * deg2Rad; end; do idx = 1 to dim(norms); angleRads = startAngle + angleIncr * (idx - 1); xComp = cos(angleRads); yComp = sin(angleRads); rdX = norms[idx] * xComp; rdY = norms[idx] * yComp; value = values[idx]; /* Parameter axis */ radAxisX = 1.1 * xComp; radAxisY = 1.1 * yComp; radAxisLabel = axisLabels[idx]; /* Parameter name */ varName = varNames[idx]; output; end; /* Reset values to avoid overwrites */ rdX = . ; rdY = . ; radAxisX = . ; radAxisY = . ; /* Generate a 'circle' polygon: * sgpanel does not have ellipseParm */ %let interPolate=6; do idx = 1 to &interPolate. * dim(norms); angleRads = startAngle + (angleIncr / &interPolate.) * (idx - 1); maxGridX = cos(angleRads); maxGridY = sin(angleRads); output; end; run; ods _all_ close; ods html dpi=200; ods graphics / reset height=620px width=600px; proc sgpanel data=radarPoly aspect=1.0; title "Top &nTop. MSRP Cars"; panelBy model / columns=4 sort=data noVarName spacing=4 noBorder; colAxis display=none alternate; /* alternate: removes secondary axis line */ rowAxis display=none alternate; polygon id=model x=rdX y=rdY / group=make fill transparency=0.2; polygon id=model x=maxGridX y=maxGridY / lineAttrs=(color=lightGray); vector x=radAxisX y=radAxisY / xOrigin=0 yOrigin=0 noArrowHeads lineAttrs=(color=lightgray); scatter x=radAxisX y=radAxisY / markerChar=radAxisLabel; footnote "Parameters: " height=9pt " $ = MSRP M = MPG City L = Length H = Horsepower W = Weight"; run;