Show percentages for bar charts with PROC SGPLOT

It seemed like an easy task. A SAS user asked me how to use the SGPLOT procedure to create a bar chart where the vertical axis shows percentages instead of counts.

I assumed that there was some simple option that would change the scale of the vertical axis from counts to percentages. After all, if you use the BARCHART statement in the GTL, you can use the STAT=PCT option to accomplish this. Unfortunately, PROC SGPLOT in SAS 9.3 does not support the STAT=PCT option. I checked the SAS 9.3 documentation for the VBAR statement several times, but, by golly, I didn't see any option that sets the scale!

At last I concluded that I would need to pre-compute the percentages and use the RESPONSE= option on the VBAR statement to specify the scale of the vertical axis.

One-way frequencies and bar charts

Assume that you want to display percentages instead of counts. If you are creating a bar chart for a one-way analysis of a categorical variable, the easiest way to visualize the categories is to use the ODS graphics in PROC FREQ. The TABLES statement supports creating a bar chart, and you can specify the scale of the vertical axis with the SCALE= option, as follows:

/* Frequency plot of percentages for one variable */
ods graphics on;
proc freq;
tables Origin / plots=FreqPlot(scale=Percent) out=Freq1Out; /* save Percent variable */

However, sometimes you might want to use the SGPLOT procedure, especially if you want to add titles or reference lines, or otherwise change the default properties of the bar chart. In that case, you can use the information in the Freq1Out data set that is created by the OUT= option on the TABLES statement. The Percent variable contains values in the range [0, 100]. I sometimes like to use values in the range [0,1]. The following DATA step divides by 100 and applies the PERCENTw.d format before plotting the summarized data:

/* use PROC SGPLOT to create a bar chart that shows percentages */
/* optional: divide by 100 and apply PERCENTw.d format */
data Freq1Out;
   set Freq1Out;
   Percent = Percent / 100;  /* adjust range to [0, 1] */
   format Percent PERCENT5.;
proc sgplot data=Freq1Out;
vbar Origin / response=Percent;  /* axis shows percentages instead of counts */

Two-way frequencies and grouped bar charts

The same trick works if you want to create a grouped bar chart. As before, you can create the bar chart directly by using the ODS graphics in PROC FREQ:

/* Frequency plot of percentages for two variables */
proc freq;
tables Origin*Type / plots=FreqPlot(twoway=cluster scale=Percent) out=Freq2Out;

The bar chart looks very similar to the bar chart that is produced by using the SGPLOT procedure and the summarized data in the Freq2Out data set:

/* use PROC SGPLOT to create a grouped bar chart that shows percentages */
/* optional: divide by 100 and apply PERCENTw.d format */
data Freq2Out;
   set Freq2Out;
   Percent = Percent / 100;
   format Percent PERCENT5.;
proc sgplot data=Freq2Out;
vbar type /group=Origin groupdisplay=cluster response=Percent;

Notice an interesting difference in the two-way (grouped) bar chart: the FREQ procedure plots empty categories, such as the category of European trucks, whereas the SGPLOT procedure does not. Of course, the biggest difference between the PROC FREQ bar charts and the PROC SGPLOT bar charts are the washed-out colors in the PROC FREQ graphs. In order to show grid lines in the background, the template for the FREQ bar chart uses semi-transparent bars, which results in the washed-out colors.

In conclusion, yes, you can use PROC SGPLOT to create a bar chart that shows percentages, but you need to pre-compute the percentages. Can you think of a different way to accomplish this task?

tags: Statistical Graphics


  1. Bhupinder Singh Farm
    Posted December 3, 2012 at 9:40 am | Permalink

    Rick, thanks for sharing the trick. One of the other options that is missing in VBAR statement in SGPLOT is to specify Y or Y2 axis. I had to use GTL to create two Y axes. It would be much easier if user have that control in VBAR statement. Second but also important missing option on VBAR is to specify the numeric format of labels. If users use STAT options (MEAN) then in the current SGPLOT procedure there is no way to control the number of significant digits. Third and last missing component that is bothering me alot these days is to control the order of character categories on X-axis. I have to use DATASTEP procedure to control it.

  2. Joshua W.
    Posted January 30, 2013 at 3:53 pm | Permalink

    Could you please provide the code for SAS 9.2 to create the plot with percentage?


    • Sanjay Matange Sanjay Matange
      Posted February 4, 2013 at 11:14 am | Permalink

      The process is the same for the basic VBAR at SAS 9.2. For the grouped case, you need to use a different process as described here: Percent VBAR.

  3. Mario Segal
    Posted March 27, 2013 at 9:51 am | Permalink

    I have a related question, I would also like to add the Ns to the bottom of the bars - that way a person can get the percentages and also the total number per bar.

    In sgplot I am able to add another vbar with the Ns, and place the values as well

    I was able to overlay 2 vbars, with the pct one being the second one and that works because they are on the initial scale so the percentages show at the bottom and the bars are not visible (but there)

    however, this is not what I wanted, I wanted percentages on top of bars and Ns at the bottom - anyone knows how to achieve this? reversing the vbar statements does not work as then the Ns in diffeent colors obscure the %s

    • Posted March 27, 2013 at 10:38 am | Permalink

      I think you can use the VBARPARM statement instead of the VBAR statement. The VBARPARM statement has a DATALABEL= and a DATALABELPOS= option that you can use to display the labels (the N values).

      If you run into trouble, post your question and example data to the SAS/GRAPH and ODS Graphics Support Community.

  4. Bart
    Posted September 24, 2013 at 1:26 pm | Permalink

    Thanks for the workaround in 9.3!

    I just spent the morning trying to figure out why everything I saw for vbar had stat=pct available. Then I realized I was searching for: "sas 9.4 sgplot stat" and not SAS 9.3... (upgrading this week, so my head was already there...)

    So it appears that stat=pct /is/ available in 9.4.

3 Trackbacks

  1. [...] can see the relative size ("market share") of the Top 20 categories. You can plot percentages instead of counts, and the percentages will be correctly interpretable as a percentage of the whole. The graph shows [...]

  2. By Percent VBar - Graphically Speaking on February 4, 2013 at 11:11 am

    [...] a reader chimed in with a question on the Do Loop article by Rick Wicklin on how to create a bar chart with percent statistics.  Rick used SAS 9.3  [...]

  3. […] procedure that can create dozens of graphs. For example, PROC FREQ can create a mosaic plot and a clustered bar chart to visualize frequencies and relative frequencies in a two-way table. Next time you use PROC FREQ, […]

Post a Comment

Your email is never published nor shared. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>