Hi Everyone, I came across the following paper to create the bar graph with error bars which have the use for me. Unfortunately when I tried the code, it throwing note that error bares are supressed... ( Please see the log image).
Reference of the Article: https://www.lexjansen.com/pharmasug-cn/2019/DV/Pharmasug-China-2019-DV85.pdf
Figure 3
Log:
1. How to create the stack graph similar to the graph? I am producing the graph like below
2. How to avoid the line between two panels (highlighted in the image below).
Thank you .
data have;
input trt$ agegrp$ response $ 6-25 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 32.1 34.2
X a Complete Response 9 33 32.4 34.2
X b Complete Response 23 25 22.4 28.1
X b Complete Response 3 25 22.4 28.1
Y a Partial Response 24 27 24.2 30.4
Y a Partial Response 4 27 24.2 30.4
Y b Partial Response 17 19 18.1 22.5
Y b Partial Response 1 19 18.1 22.5
;
run;
title '';
title 'Figure 8 data- sgplot- bargraph plot';
ods html;
PROC sgplot data=have;
*panelby trt / layout=columnlattice colheaderpos=bottom;
vbarparm category=agegrp response=omean / group=response limitlower=lowerclm
limitupper=upperclm;
run;
PROC sgpanel data=have;
panelby trt / layout=columnlattice colheaderpos=bottom;
vbarparm category=agegrp response=omean / group=response limitlower=lowerclm
limitupper=upperclm;
run;
ods _all_ close;
OK. How about this one ?
data have;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 60.1 74.2
X a Partial Response 9 33 . .
X b Complete Response 23 25 42.4 58.1
X b Partial Response 3 25 . .
Y a Complete Response 24 27 44.2 58.4
Y a Partial Response 4 27 . .
Y b Complete Response 17 19 34.1 46.5
Y b Partial Response 1 19 . .
;
run;
PROC sgpanel data=have ;
styleattrs datacolors=(green white) datacontrastcolors=(green grey);
panelby trt / layout=columnlattice colheaderpos=bottom spacing=0 noborder novarname ;
vbarparm category=agegrp response=omean / group=response groupdisplay=stack fillpattern;
highlow x=agegrp low=lowerclm high=upperclm/ HIGHCAP=SERIF LOWCAP=SERIF lineattrs=(color=black);
run;
First bit your data step. The data for orr starts in column 24 so all sorts of problems read column 6 to 23 with the data as pasted.
213 data have; 214 input trt$ agegrp$ response $ 6-25 orr omean lowerclm upperclm; 215 cards; NOTE: Invalid data for upperclm in line 217 1-1. RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+-- 217 X a Complete Response 9 33 32.4 34.2 trt=X agegrp=a response=Complete Response 28 orr=33 omean=32.1 lowerclm=34.2 upperclm=. _ERROR_=1 _N_=1 NOTE: Invalid data for upperclm in line 219 1-1. 219 X b Complete Response 3 25 22.4 28.1 trt=X agegrp=b response=Complete Response 23 orr=25 omean=22.4 lowerclm=28.1 upperclm=. _ERROR_=1 _N_=2 NOTE: Invalid data for upperclm in line 221 1-1. 221 Y a Partial Response 4 27 24.2 30.4 trt=Y agegrp=a response=Partial Response 24 orr=27 omean=24.2 lowerclm=30.4 upperclm=. _ERROR_=1 _N_=3 NOTE: Invalid data for upperclm in line 223 1-1. 223 Y b Partial Response 1 19 18.1 22.5 trt=Y agegrp=b response=Partial Response 17 orr=19 omean=18.1 lowerclm=22.5 upperclm=. _ERROR_=1 _N_=4 NOTE: SAS went to a new line when INPUT statement reached past the end of a line. NOTE: The data set WORK.HAVE has 4 observations and 7 variables.
Next sgpanel throws this:
ERROR: The sort order of the data set cannot be validated. Please sort your data. NOTE: The SAS System stopped processing this step because of errors. NOTE: PROCEDURE SGPANEL used (Total process time): real time 0.02 seconds cpu time 0.01 seconds
After sorting by TRT to allow the Panelby we all sorts of the data is not proper.
274 PROC sgpanel data=have; 275 panelby trt / layout=columnlattice colheaderpos=bottom 276 noborder; 277 vbarparm category=agegrp response=omean / group=response limitlower=lowerclm 278 limitupper=upperclm; 279 run; NOTE: PROCEDURE SGPANEL used (Total process time): real time 0.26 seconds cpu time 0.04 seconds NOTE: Error bars are suppressed when the GROUPDISPLAY=STACK or GROUP100=POSITIVE|MAGNITUDE option is used. NOTE: Error bars are suppressed when the GROUPDISPLAY=STACK or GROUP100=POSITIVE|MAGNITUDE option is used. WARNING: The data for a BARCHARTPARM statement are not appropriate. The BARCHARTPARM statement expects summarized data. The bar chart might not be drawn correctly. NOTE: Error bars are suppressed when the GROUPDISPLAY=STACK or GROUP100=POSITIVE|MAGNITUDE option is used. NOTE: Error bars are suppressed when the GROUPDISPLAY=STACK or GROUP100=POSITIVE|MAGNITUDE option is used. WARNING: The data for a BARCHARTPARM statement are not appropriate. The BARCHARTPARM statement expects summarized data. The bar chart might not be drawn correctly. NOTE: There were 8 observations read from the data set WORK.HAVE.
The article you referenced has this bit of code to use VBARPARM:
PROC MEANS data=bardata1 mean lclm uclm; class trt; var orr; output out=bardata2 mean=orrmean lclm=lowerclm uclm=upperclm; run;
But their code Plots Bardata3, which seems to be missing for how it may have been built and uses an option Panelby with SGPLOT that is not documented: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.4/grstatproc/p1t32i8511t1gfn17sw07yxtazad.htm as a reference.
So I am fairly sure that the code in that document did not generate the graph shown. So I suspect that perhaps a GTL (Graph Template Language) approach may have been involved or an annotate set or possibly create a graph with VBARBASIC and used another plot to over the desired error bar image.
The default for Groupdisplay with any of the Vbar, Vbarparm, Hbar, Hbarparm is stack. So you can try groupdisplay = cluster which places things side by side and would allow the error bars PER bar.
Apologies for wrong code for dataset creation. I believe I forgot to change the input response length ( reading 6-23) after modifying the trt varaible (length to $1). I corrected that. From your explanation can I conclude to the following.
1. There is no way we can have the error bars on the stacked VBARS graph using SGPLOT or PANEL.
2. I see the code SGPLOT in the paper which have the PANEL statement. I think SGPLOT can't have panel statement ! correct me if I am wrong.
Thank you for your time and explanation. I will try for the GTL approach.
*corrected code for dataset creation;
data have;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 32.1 34.2
X a Complete Response 9 33 32.4 34.2
X b Complete Response 23 25 22.4 28.1
X b Complete Response 3 25 22.4 28.1
Y a Partial Response 24 27 24.2 30.4
Y a Partial Response 4 27 24.2 30.4
Y b Partial Response 17 19 18.1 22.5
Y b Partial Response 1 19 18.1 22.5
;
run;
proc sort data= have; by trt; run
data have;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 52.1 64.2
X b Complete Response 23 25 40.4 52.1
Y a Partial Response 24 27 . .
Y b Partial Response 17 19 . .
;
run;
proc sort data= have; by trt; run;
title 'Figure 8 data- sgplot- bargraph plot';
PROC sgplot data=have;
vbarparm category=agegrp response=omean / group=response ;
highlow x=agegrp low=lowerclm high=upperclm/ HIGHCAP=SERIF LOWCAP=SERIF lineattrs=(color=black);
run;
data have2;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 22.1 34.2
X b Complete Response 23 25 20.4 32.1
Y a Partial Response 24 27 25 30
Y b Partial Response 17 19 12 22
;
run;
PROC sgpanel data=have2 ;
panelby trt / layout=columnlattice colheaderpos=bottom spacing=0 noborder ;
vbarparm category=agegrp response=omean / group=response ;
highlow x=agegrp low=lowerclm high=upperclm/ HIGHCAP=SERIF LOWCAP=SERIF lineattrs=(color=black);
run;
Thank you @Ksharp for your solution. There is slight change in the data. I am attaching the data code. I am looking how I can Stack the bars on top of each other and have the treatments in two panels like Reference Image in green bars . With the new data I am looking to get Red Bar of 'Partial response' and have the error bars have to be stacked over the 'Complete response' blue color Bar but I am getting side by side. PS: We have the flexibility to modify the data as per out requirement like how you did it for ' hhave2' dataset.
Graph I am getting with new Data:
Reference Image:
*New Dataset code;
data have;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 32.1 34.2
X a Partial Response 9 33 32.4 34.2
X b Complete Response 23 25 22.4 28.1
X b Partial Response 3 25 22.4 28.1
Y a Complete Response 24 27 24.2 30.4
Y a Partial Response 4 27 24.2 30.4
Y b Complete Response 17 19 18.1 22.5
Y b Partial Response 1 19 18.1 22.5
;
run;
OK. How about this one ?
data have;
input trt$ agegrp$ response $ 6-23 orr omean lowerclm upperclm;
cards;
X a Complete Response 28 33 60.1 74.2
X a Partial Response 9 33 . .
X b Complete Response 23 25 42.4 58.1
X b Partial Response 3 25 . .
Y a Complete Response 24 27 44.2 58.4
Y a Partial Response 4 27 . .
Y b Complete Response 17 19 34.1 46.5
Y b Partial Response 1 19 . .
;
run;
PROC sgpanel data=have ;
styleattrs datacolors=(green white) datacontrastcolors=(green grey);
panelby trt / layout=columnlattice colheaderpos=bottom spacing=0 noborder novarname ;
vbarparm category=agegrp response=omean / group=response groupdisplay=stack fillpattern;
highlow x=agegrp low=lowerclm high=upperclm/ HIGHCAP=SERIF LOWCAP=SERIF lineattrs=(color=black);
run;
This looks perfect. Thank you. Just quick question for my knowledge purpose. I see a new dataset '_sgsrt2_' creating with one extra variable .. when I run the SGPANEL code even though there is no 'out' option, why? I am using your exact code.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.
Ready to level-up your skills? Choose your own adventure.