/*******************************************/ /* BLOG 2: Mosaic plots by using PROC FREQ */ /* Rick Wicklin: Blog post 11/6/2013 */ /* http://blogs.sas.com/content/iml/2013/11/06/create-mosaic-plots-in-sas-by-using-gtl */ /*******************************************/ proc format; value WtFmt 1 = 'Underweight' 2 = 'Normal' 3 = 'Overweight'; value SmFmt 1 = 'Non-smoker' 2 = 'Light (1-5)' 3 = 'Moderate (6-15)' 4 = 'Heavy (16-25)' 5 = 'Very Heavy (> 25)'; value BPFmt 1 = 'Optimal' 2 = 'Normal' 3 = 'High'; run; data Heart / view=Heart; format Smoking_Cat SmFmt. Weight_Cat WtFmt. BP_Cat BPFmt.; set sashelp.heart; select (Weight_Status); when ('Underweight') Weight_Cat=1; when ('Normal') Weight_Cat=2; when ('Overweight') Weight_Cat=3; when (' ') Weight_Cat=.; end; select (Smoking_Status); when ('Non-smoker') Smoking_Cat=1; when ('Light (1-5)') Smoking_Cat=2; when ('Moderate (6-15)') Smoking_Cat=3; when ('Heavy (16-25)') Smoking_Cat=4; when ('Very Heavy (> 25)') Smoking_Cat=5; when (' ') Smoking_Cat=.; end; select (BP_Status); when ('Optimal') BP_Cat=1; when ('Normal') BP_Cat=2; when ('High') BP_Cat=3; when (' ') BP_Cat=.; end; run; /* summarize the data */ proc freq data=heart; tables BP_Cat*Weight_Cat / out=FreqOut(where=(Percent^=.)); run; /* create basic mosaic plot with no tile colors */ proc template; define statgraph BasicMosaicPlot; begingraph; layout region; MosaicPlotParm category=(Weight_Cat BP_Cat) count=Count; endlayout; endgraph; end; run; proc sgrender data=FreqOut template=BasicMosaicPlot; run; /* custom colors in mosaic plots */ /* summarize the data */ proc freq data=heart; tables BP_Cat*Weight_Cat / norow cellchi2 expected stdres crosslist; ods output CrossList=FreqList(where=(Expected>0)); run; /* color by response (notice that PROC FREQ reverses Y axis) */ proc template; define statgraph mosaicPlotParm; begingraph; layout region; MosaicPlotParm category=(Weight_Cat BP_Cat) count=Frequency / colorresponse=StdResidual name="mosaic"; continuouslegend "mosaic" / title="StdRes"; endlayout; endgraph; end; run; proc sgrender data=FreqList template=mosaicPlotParm; run; /* adjust range for color ramp values */ proc template; define statgraph mosaicPlotParm2; begingraph; /* define the attribute map and assign the name */ rangeattrmap name="responserange" ; range negmaxabs - maxabs / rangecolormodel=ThreeColorRamp; endrangeattrmap ; /* assign variable name RANGEVAR to the named association */ rangeattrvar attrvar=rangevar var=StdResidual attrmap="responserange"; layout region; MosaicPlotParm category=(Weight_Cat BP_Cat) count=Frequency / colorresponse=rangevar name="mosaic"; continuouslegend "mosaic" / title="StdRes"; endlayout; endgraph; end; run; proc sgrender data=FreqList template=mosaicPlotParm2; run; /* adjust range of values for color ramp; add dynamic variables */ proc template; define statgraph mosaicPlotGen; dynamic _X _Y _Frequency _Response _Title _LegendTitle; begingraph; entrytitle _Title; rangeattrmap name="responserange" ; range negmaxabs - maxabs / rangecolormodel=ThreeColorRamp; endrangeattrmap ; rangeattrvar attrvar=rangevar var=_Response attrmap="responserange"; layout region; MosaicPlotParm category=(_X _Y) count=_Frequency / name="mosaic" colorresponse=rangevar; continuouslegend "mosaic" / title=_LegendTitle; endlayout; endgraph; end; run; proc sgrender data=FreqList template=mosaicPlotGen; dynamic _X="Weight_Cat" _Y="BP_Cat" _Frequency="Frequency" _Response="StdResidual" _Title="Blood Pressure versus Weight" _LegendTitle="StdResid"; run;