10-24-2014 07:35 AM
Thought this might be doable via attribute maps, but can't quite seem to do it.
I am using SGPANEL to draw histograms of patient ages across four disease areas and what I would really like to be able to do is have the area/proportion of patients who are aged 75 or over have a different fill color such that it is very easy to see at a glance which disease area has the highest proportion of patients above the specified threshold. Any ideas?
many thanks, Chris
10-24-2014 08:39 AM
I don't know how to do this using PRC SGPANEL, but below is a code using PROC TEMPLATE + PROC SGRENDER:
*say you want to differentiate children older than 12;
*I created two variables out of AGE: age_below and age_above;
IF AGE <= 12 THEN AGE_BELOW = AGE;
ELSE AGE_ABOVE = AGE;
*tell SAS to save my graph in this location;
ODS LISTING GPATH = "GivePath";
*give a name to my graph;
ODS GRAPHICS/RESET IMAGENAME = "SPLIT_HIST";
*write the template to create the histogram with two colors;
*the first few lines are telling SAS how wide and long I want to graph, then gives some graph space preferences;
*notice the two histogram statements (which I overlay), one for the below variable, one for the above variable;
DEFINE STATGRAPH Hist2Colors;
BEGINGRAPH / DESIGNWIDTH=1074 DESIGNHEIGHT=724;
LAYOUT LATTICE / ROWDATARANGE=DATA COLUMNDATARANGE=DATA ROWGUTTER=10 COLUMNGUTTER=10;
LAYOUT OVERLAY / XAXISOPTS=( LABEL=('AGE'));
HISTOGRAM AGE_ABOVE / NAME='HISTOGRAM' BINWIDTH=1.0 FILLATTRS=GRAPHDATA1 OUTLINEATTRS=GRAPHDATA1;
HISTOGRAM AGE_BELOW / NAME='HISTOGRAM2' BINAXIS=FALSE BINWIDTH=1.0;
*the sgrender procedure will render the template
PROC SGRENDER DATA=WORK.HAVE TEMPLATE=Hist2Colors;
I hope it helps.
Best of luck!
10-24-2014 12:06 PM
You can do this with SGPANEL too. If your data has a class variable for the four disease areas, and you divide the analysis column into two as suggested by Anca has done above,you can overlay the two histograms in each cell of the 4 panel graph.
label systolicGT60='Age > 60' systolicLE60='Age <= 60';
set sashelp.heart(keep=systolic ageatstart deathcause);
if ageatstart > 60 then systolicGT60=Systolic;
title 'Distribution of Systolic Blood Pressure by Death Cause and age';
proc sgpanel data=heart(where=(deathcause ne ''));
panelby deathcause / layout=columnlattice columns=5 onepanel novarname;
histogram systolicGT60 / transparency=0.5;
histogram systolicLE60 / transparency=0.5;
11-03-2014 06:13 AM
Many thanks for taking the time to answer Anca and Sanjay, it is much appreciated (and forgive the late reply ... was away on holiday last week). My eyes have been opened to PROC TEMPLATE and SGRENDER so I am well on the way to learning some new tools. However, your answers don't quite solve my original problem. This is my fault for not being specific enough in my original question, but these solutions overlay two histograms (per disease) split on age. What I really want is one histogram (per disease) with different shading beyond a certain point. I cannot treat them as two different histograms because the percentage values get messed up.
The first image shows the correct histogram, but I would like the area to the right of 75 in each graph to be red and the second image shows the problem with the histograms themselves if I adopt the solutions above.
11-03-2014 08:37 AM
AS soon as I posted my answer, I realized ...ehh, that's not a solution.
Well, here is something soooo tedious, but does what you want:
(this is going back to good ol' style: annotate!)
*--create an annotate dataset, that will force to color bins based on VERY specific values;
length function style color $ 8 ;
xsys="3"; ysys="3";when = "a";
ods graphics off;
proc univariate data = sashelp.class anno = boxColor;
var age;histogram age;
Now let me know if you have questions.
11-03-2014 09:09 AM
Here is one way, but needs a little bit of GTL. The idea is to run a SGPLOT histogram, and get the binned data. Then use GTL to overlay two HistogramParm statements, each with part of the data and different colors.
But you cannot get the transition bin to have partial colors. I have seen that done too,by using a band plot to really draw the color bands, and then overlay it with an unfilled histogram having same bins..
ods html close;
ods listing image_dpi=200;
ods output sgplot=sgplotData;
ods graphics / reset width=5in height=3in imagename='Hist';
proc sgplot data=sashelp.heart;
histogram ageatstart / nbins=50;
set sgplotData(rename=(bin_ageatstart_nbins_50___x=x bin_ageatstart_nbins_50___y=y));
if x and y;
define statgraph HistBins;
entrytitle 'Distribution by Age';
layout overlay / xaxisopts=(label='Age at Start');
histogramparm x=eval(ifn(x<=50, x, .)) y=y / fillattrs=graphdata1 binaxis=false name='a' legendlabel='Age < 50';
histogramparm x=eval(ifn(x>50, x, .)) y=y / fillattrs=graphdata2 binaxis=false name='b' legendlabel='Age >= 50';
discretelegend 'a' 'b' / location=inside across=1 autoalign=(topright);
ods graphics / reset width=5in height=3in imagename='TwoColorHist';
proc sgrender data=HistBins template=HistBins;