I am creating a panel plot of AE's by grade over time using SGPANEL (9.4 M5). Truth is, I have no idea what I am doing, but thanks to so many wonderful people sharing their wisdom I've got a decent graph.
I'm trying to add the denominator to the x-axis, as the N's change over time. I've tried COLAXISTABLE, but the bars are a sum of AE grades and I only want the denominator to display once (versus multiple times for each grade).
In my borrowing of code, I found this: https://communities.sas.com/t5/Graphics-Programming/Wrap-SGPANEL-Column-Headers-9-3/td-p/416411 which lead me to try and format a numeric PANELBY variable. It works nicely if I display 12 months. But when I go out to say, 24 months, I can't seem to get the x-axis to wrap (e.g., month on one line and the (N=X) on a line below). I've tried inserting line breaks, but haven't had success. Any help is greatly appreciated! Code, data and example plot attached.
Unless you have real long program it is best to post code into a code box for easy reference.
In your format try adding a special character such as the *
proc format; value avalfmt %macro loopit; %do a = 1 %to 24; &a = "&a *(N=&&n&a)" %end; %mend loopit; %loopit; ; run;
And in your sgpanel use a COLAXIS statement with the option SPLITCHAR="*" (or which ever special character you use in the format where I used the *).
The Splitchar option should force a second (or even third row) axis label when the character is present in the displayed value.
However you may still run into issues with the number of ticks displayed.
Thanks so much for the suggestion! I had tried that before but figured why not, I'll try it again. But sadly, it didn't work for me. Maybe I'm doing something wrong. Thanks though!
Are you also setting FITPOLICY=SPLIT on the XAXIS?
May I start by saying what an honor it is to see a reply from the Brad Pitt of SAS graph? I guess that makes Sanjay the George Clooney? Maybe? Quarantine getting to me? Probably. In any case, I tried it again, making sure I added that and still no dice. I'm starting to wonder if I picked the wrong means of graphing this. The example I attached is for one treatment group, but an earlier version had two bars in each panel, one for each of two treatment groups. So I felt like SGPANEL was a good fit. But really, I have no idea what I am doing! Here's my code again, adding the splitchar and fitpolicy. I had added the asterisk to the proc format as well, as suggested. Resulting figure is attached. I don't know if the issue is I have a two-level x-axis (treatment group and month) and I am using proc format so it's not recognizing the splitchar? I tried COLAXISTABLE (commented out below) but that didn't work for me (at least as I intended), because it displayed N's for every grade level and I only wanted them once. Thanks for the help!
proc sgpanel data=forfig3 description="#byval1"; format pct mypct.; format avaln avalfmt.; by dtype2; styleattrs datacolors=(CX008000 CXFFFF00 CXFFA500 CXFF0000 CX000000); panelby avaln / layout=columnlattice colheaderpos=bottom novarname noborder columns=24 proportional spacing=0 uniscale=row missing noheaderborder headerattrs=(family=arial size=8); vbar trtp / response=pct stat=sum group=atoxgrn barwidth=.6 clusterwidth=1 datalabel datalabelattrs=(size=7 family=arial) ; colaxis fitpolicy=split splitchar="*" display=(novalues noticks) label='Month' labelpos=left labelattrs=(size=9 family=arial); * the colaxistable is not working so well bc it wants to plot Ns for all levels of ATOXGRN, will instead add Ns to AVAL *; *colaxistable denom / nomissingchar nomissingclass valueattrs=(color=blue); rowaxis grid min=0 max=100 offsetmin=.01 offsetmax=.01 values=(0 to 75 by 25) labelattrs=(size=10 family=arial) valuesformat=best4.0 valueattrs=(size=8 family=arial) Label="Percent"; keylegend / noborder titleattrs=(size=9 family=arial) position=bottom title='Maximum Grade'; run;
The issue I was seeing is that your "column axis labels" are actually the panel headers from the panelby statement and these are not affected by COLAXIS as far as I know. I noticed that your TRTP variable was all the same value, so I changed your code to be an SGPLOT using the AVALN variable as the category variable instead. This puts the values into the x-axis which are then affected by the SPLITPOLICY. I made the graph wider as well since the labels are still squished.
ods graphics / width=15in;
proc sgplot data=forfig3 description="#byval1";
format pct mypct.;
format avaln avalfmt.;
by dtype2;
styleattrs datacolors=(CX008000 CXFFFF00 CXFFA500 CXFF0000 CX000000);
vbar avaln / response=pct stat=sum group=atoxgrn barwidth=.6 clusterwidth=1 datalabel datalabelattrs=(size=7 family=arial) ;
xaxis fitpolicy=splitalways splitchar="*" label='Month' labelpos=left labelattrs=(size=9 family=arial);
yaxis grid min=0 max=100 offsetmin=.01 offsetmax=.01 values=(0 to 75 by 25) labelattrs=(size=10 family=arial) valuesformat=best4.0 valueattrs=(size=8 family=arial) Label="Percent";
keylegend / noborder titleattrs=(size=9 family=arial) position=bottom title='Maximum Grade';
run;
Thanks!!! That worked. Very cool. Is it possible to use this method (SGPLOT) to accommodate 2 treatment groups side by side at each month? My first iteration of this graph went out 12 months and had 2 groups (drug/placebo). I was then asked to run the same graph on a different group (all treated). I'd love to have code that could work in either situation (1 vs >1 treatment groups). Thank you so much!
How do you want the different groups shown? In different panels, with bars next to each other, or some other way? If it's in different panels then you could use your treatment variable in your PANELBY statement in SGPANEL and try similar code to make 2 or more different groups.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.