Hello all,
Thanks again for the great code on creating a butterfly chart. Here's the basic code I'm using but now I'd like to enhance it to include both the value in parentheses below the percentage. (see picture).
Thanks for your great help!
proc format;
picture posval low-<0='00000%'
(prefix='-')
0='9%'
0<-high='00000%';
run;
data have;
call streaminit(123);
do date='01jan2022'd to '20jan2022'd;
value=rand('integer',-100,100);
group=ifc(value>0,'pos_diff','neg_diff');
output;
end;
format date date9. value posval.;
run;
proc sgplot data=have;
hbarparm category=date response=value/group=group datalabel=value
GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=INSIDEPREFERRED
;
keylegend /title='';
yaxis label='';
xaxis label='';
run;
/*
Try TEXT statement
*/
proc format;
picture posval low-<0='00000%'
(prefix='-')
0='9%'
0<-high='00000%';
run;
data have;
call streaminit(123);
do date='01jan2022'd to '20jan2022'd;
value=rand('integer',-100,100);
n=rand('integer',100,1000);
group=ifc(value>0,'pos_diff','neg_diff');
if value>0 then datalabel_pos=cats(value,"%|(",n,")");
else datalabel_neg=cats(value,"%|(",n,")");
output;
call missing(datalabel_pos,datalabel_neg);
end;
format date date9. value posval.;
run;
proc sgplot data=have;
hbarparm category=date response=value/group=group name='x' ;
text x=value y=date text=datalabel_pos/splitchar='|' strip contributeoffsets=none
SPLITCHAR='|' SPLITJUSTIFY=left SPLITPOLICY=splitalways position=right ;
text x=value y=date text=datalabel_neg/splitchar='|' strip contributeoffsets=none
SPLITCHAR='|' SPLITJUSTIFY=left SPLITPOLICY=splitalways position=left ;
keylegend 'x'/title='';
yaxis label=' ';
xaxis label=' ' offsetmin=0.1 offsetmax=0.1;
run;
Vertical stacking of multiple text items means that you will have to consider some things such as the width of your bars and the font size of the text. Otherwise you are going to have visual alignment issues. Also how many variables are involved? If you try to use a data label with value and have the additional text in a different variable you will have some fun getting the things not to overlap or collide.
How critical is having the text immediately at the end of the bars? Yaxis tables on the edge of the display area might be more flexible in the long run.
Is the other text, the apparent count, going to be in a separate variable? or will have both the percentage and count in a single variable (which can no longer be used as a Response variable, okay for Group but not response).
Side by side is easier by far.
data have;
call streaminit(123);
do date='01jan2022'd to '20jan2022'd;
value=rand('integer',-100,100);
value_num = value*1000;
location = value-1;
group=ifc(value>0,'pos_diff','neg_diff');
text_display = catx(", ", value_num, value);
output;
end;
format date date9. value posval.;
run;
proc sgplot data=have;
hbarparm category=date response=value/group=group
GROUPDISPLAY=CLUSTER
;
text x=location y=date text=text_display;
keylegend /title='';
yaxis label='';
xaxis label='';
run;
/*
Try TEXT statement
*/
proc format;
picture posval low-<0='00000%'
(prefix='-')
0='9%'
0<-high='00000%';
run;
data have;
call streaminit(123);
do date='01jan2022'd to '20jan2022'd;
value=rand('integer',-100,100);
n=rand('integer',100,1000);
group=ifc(value>0,'pos_diff','neg_diff');
if value>0 then datalabel_pos=cats(value,"%|(",n,")");
else datalabel_neg=cats(value,"%|(",n,")");
output;
call missing(datalabel_pos,datalabel_neg);
end;
format date date9. value posval.;
run;
proc sgplot data=have;
hbarparm category=date response=value/group=group name='x' ;
text x=value y=date text=datalabel_pos/splitchar='|' strip contributeoffsets=none
SPLITCHAR='|' SPLITJUSTIFY=left SPLITPOLICY=splitalways position=right ;
text x=value y=date text=datalabel_neg/splitchar='|' strip contributeoffsets=none
SPLITCHAR='|' SPLITJUSTIFY=left SPLITPOLICY=splitalways position=left ;
keylegend 'x'/title='';
yaxis label=' ';
xaxis label=' ' offsetmin=0.1 offsetmax=0.1;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: