BookmarkSubscribeRSS Feed
tammy_dezilva
Quartz | Level 8

Hi

I am wanting to display the values of each segment within a stacked bar chart that is also grouped.  I am having trouble understanding what is needed for the annotate dataset.

Below is my code to create a sample table, a annoate table and then create my graph.  The graph creates as I want it to without the sganno option.  I just need to be able to put the values i.e. numerator, in each of the segments on the stacked bar chart. Any help would be greatly appreciated or if I can do a stacked bar chart that is grouped with the labels any other way??

thanks

Tammy

data work.tam;
infile datalines dlm=',';
input Risk $ Numerator Service RptDate $;
datalines;
A,5,1,Begin
A,8,1,End
B,3,1,Begin
B,9,1,End
C,1,1,Begin
C,4,1,End
A,2,2,Begin
A,6,2,End
B,4,2,Begin
B,1,2,End
C,6,2,Begin
C,3,2,End
;
run;

data work.anno;
set work.tam;
retain function "text" xspace "datavalue";
label=put(numerator,comma10.);
yc1=strip(put(numerator,comma10.));
run;

proc sgpanel data=work.tam sganno=work.anno;
   panelby service / layout=columnlattice onepanel noborder colheaderpos=bottom novarname;
   vbar RptDate / response=Numerator group=Risk dataskin=pressed;
   keylegend /position=right;
run;

5 REPLIES 5
BrunoMueller
SAS Super FREQ

Hi tammy

Since the annotate together with SGPANEL does not support a drawspace that supports "data",

this is from the doc:

RestrictionFor the SGPANEL and SGSCATTER procedures, only GRAPHPERCENT, GRAPHPIXEL, LAYOUTPERCENT, and LAYOUTPIXEL values are valid.

You have to go another way, in a recent blog entry by outlined a technique with HIGHLOW and SCATTER plot to do something similar to what you want.Building on that, here is a code sample for the graph you want to do, it does some data preparation so that the HIGHLOW and SCATTER plots can be used. I guess there are other solutions as well

data work.tam;
  infile datalines dlm=',';
 
input Risk $ Numerator Service RptDate $;
  key = catx("_", service, RptDate, risk );
  datalines;
A,5,1,Begin
A,8,1,End
B,3,1,Begin
B,9,1,End
C,1,1,Begin
C,4,1,End
A,2,2,Begin
A,6,2,End
B,4,2,Begin
B,1,2,End
C,6,2,Begin
C,3,2,End
;

proc sort data=work.tam;
  by key;
run;

data tam2;
  set tam;
  by service  rptdate  NOTSORTED;
 
length numLow numHigh 8;
 
retain  numHigh;

 
if first.service = 1 or first.rptdate = 1 then do;
    numlow =
0;
    numHigh = numerator;
 
end;
 
else do;
    numlow = numHigh;
    numHigh = numLow + numerator;
 
end;
  labelpos = numLow + (range(numLow, numHigh) /
2);
  labelValue = range(numLow, numHigh);
run;

proc sgpanel data=work.tam2;
  panelby service /
   
layout=columnlattice onepanel noborder colheaderpos=bottom novarname
  ;
  highlow x=RptDate low=numlow high=numhigh /
   
group=Risk type=bar name="hl"
  ;

 
scatter x=rptDate y=labelpos /
   
datalabel=labelValue
   
datalabelpos=center
   
markerattrs=(size=0)
    labelStrip
   
name="sc"
  ;
  keylegend "hl" / position=right;
run;
GraphGuy
Meteorite | Level 14

If you can't do this conveniently in ODS Graphics, here's an alternative using SAS/Graph Gchart:

data work.tam;
infile datalines dlm=',';
input Risk $ Numerator Service RptDate $;
datalines;
A,5,1,Begin
A,8,1,End
B,3,1,Begin
B,9,1,End
C,1,1,Begin
C,4,1,End
A,2,2,Begin
A,6,2,End
B,4,2,Begin
B,1,2,End
C,6,2,Begin
C,3,2,End
;
run;

proc sort data=work.tam out=work.anno;
by service RptDate Risk;
run;
data work.anno; set work.anno;
by service RptDate;
if first.service or first.RptDate then y=0;
y+Numerator;
run;

data work.anno; set work.anno;
function='label'; position='e'; size=2.5; color='blue'; style='albany amt/bold';
xsys='2'; ysys='2'; hsys='3'; when='a';
group=service; midpoint=RptDate;
text=trim(left(put(numerator,comma10.)));
run;

legend1 label=none across=1 position=(right middle)
order=descending shape=bar(.15in,.15in) offset=(-15pct,0pct);


axis1 label=none;
axis2 label=none;
axis3 label=none order=(0 to 25 by 5) minor=none;


ods html style=sasweb;
proc gchart data=work.tam anno=work.anno;
vbar RptDate / type=sum sumvar=Numerator
subgroup=Risk group=service width=12
maxis=axis1 gaxis=axis2 raxis=axis3
noframe autoref clipref cref=graydd
legend=legend1;
run;

bar_anno.png

tammy_dezilva
Quartz | Level 8

Brilliant - thanks so much Bruno and Robert!  They both worked a treat.

Jay54
Meteorite | Level 14

Assuming you are using at least SAS 9.3.  With SG, you can do this without annotation by overlaying a SCATTER with MARKERCHAR.  Since SGPANEL VBARPARM does not support stacked groups at SAS 9.3, you can use HIGHLOW statement with TYPE=BAR.  In addition to computing the label Y position, also compute the start and end of each segment as shown in the code.

StackedBarPanelLabel.png

data work.tam;
infile datalines dlm=',';
input Risk $ Numerator Service RptDate $;
datalines;
A,5,1,Begin
A,8,1,End
B,3,1,Begin
B,9,1,End
C,1,1,Begin
C,4,1,End
A,2,2,Begin
A,6,2,End
B,4,2,Begin
B,1,2,End
C,6,2,Begin
C,3,2,End
;
run;

proc sort data=tam out=tam1;
by  service rptdate risk;
run;

data tam2;
  set tam1;
  by service rptdate risk;
  retain y2;
  if first.rptdate then do;
    y1=0; y2=y1+numerator; ys=(y1+y2)/2;
  end;
  else do;
    y1=y2; y2=y1+numerator; ys=(y1+y2)/2;
  end;
  run;

ods html close;
ods listing;
proc sgpanel data=tam2 ;
   format numerator 1.;
   panelby service / layout=columnlattice onepanel noborder colheaderpos=bottom novarname;
   highlow x=RptDate low=y1 high=y2 / group=Risk type=bar name='a' lineattrs=(color=black);
   scatter x=rptdate y=ys / markerchar=numerator markercharattrs=(size=9);
   keylegend 'a' /position=right;
   rowaxis offsetmin=0;
run;

tammy_dezilva
Quartz | Level 8

Thanks so much Sanjay, and yes I'm using v9.4.  I've been reading some of your white papers and blogs as well which have been very useful in understanding the SG procedures.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 3052 views
  • 6 likes
  • 4 in conversation