## Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

I am using SGPLOT (in SAS 9.4 1M4) to create a stacked bar chart. Each subject has 5 visits (Visit 1,2,3,4,5) and a dose at each visit. They have a total dose at each visit. My Y-axis is the total dose. The X-axis is each subject. Each stacked bar shows the total dose split up by visit.

proc sgplot data=test;
vbar subject / response=tot  /* Total Dose at each visit by subject. So each subject has 5 records to capture total dose at a visit*/

group=visit     /*Numeric 1,2,3,4,5*/

categoryorder=respasc /*Displays totals by ascending oder*/

/* grouporder=ascending ***This accomplishes the requirement to keep the visits in order. If I try to use both                                               categoryorder and grouporder options together it does not work*/;
xaxis label='Subject';
yaxis label='Total Dose';
run;

Now in each stacked bar, I need to keep the visits in the same visit order (1,2,3,4,5) instead of their dose at each visit. So right now, if visit 4 has a smaller dose than visit 1, it shows up before (bottom of the stack) the visit 1 dose in the stack. I want the stack to always display visit 1 before visit 2 and so on for each subject while still displaying the stacks in ascending order of TOTAL DOSE. How can I accomplish this?

Thanks,
Vamsi

1 ACCEPTED SOLUTION

Accepted Solutions

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Dan,

Thank you so much. The issue was to sort it by only the tot_height and then it works.

Thanks,

Vamsi

12 REPLIES 12

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

@Vamsi_77 wrote:

I am using SGPLOT (in SAS 9.4 1M4) to create a stacked bar chart. Each subject has 5 visits (Visit 1,2,3,4,5) and a dose at each visit. They have a total dose at each visit. My Y-axis is the total dose. The X-axis is each subject. Each stacked bar shows the total dose split up by visit.

proc sgplot data=test;
vbar subject / response=tot  /* Total Dose at each visit by subject. So each subject has 5 records to capture total dose at a visit*/

group=visit     /*Numeric 1,2,3,4,5*/

categoryorder=respasc /*Displays totals by ascending oder*/

/* grouporder=ascending ***This accomplishes the requirement to keep the visits in order. If I try to use both                                               categoryorder and grouporder options together it does not work*/;
xaxis label='Subject';
yaxis label='Total Dose';
run;

Now in each stacked bar, I need to keep the visits in the same visit order (1,2,3,4,5) instead of their dose at each visit. So right now, if visit 4 has a smaller dose than visit 1, it shows up before (bottom of the stack) the visit 1 dose in the stack. I want the stack to always display visit 1 before visit 2 and so on for each subject while still displaying the stacks in ascending order of TOTAL DOSE. How can I accomplish this?

Thanks,
Vamsi

From the documentation on CATEGORYORDER

 Interactions When a group variable is used with the CATEGORYORDER= option, the response values for each group segment become the sorting key. CATEGORYORDER sorts first by the response statistic and then displays the GROUP values sorted within each category.

So, do not use the categoryorder option.

Try using the GROUPORDER=ASCENDING option to use the group variable to control order of the segments.

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Yes, I already did that but then I would not be able to sort by ascending order of total dose. I need to combine the functionality of the category order and group order.  DanH_sas
SAS Super FREQ

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Here's how you can do it:

1. Using PROC SUMMARY or PROC MEANS, compute the bar height MINUS THE GROUP. Some like:

``````proc summary data=whatever nway;
class subject;
var tot;
output out=barheight sum=height;
run;

``````

2. Match merge the "barheight" data with the "whatever" data by SUBJECT.

3. PROC SORT the merged dataset by HEIGHT and VISIT.

4. Use VBARPARM instead of VBAR to render the chart. Be sure to set DISCRETEORDER=DATA on the XAXIS statement.

Hope this helps!

Dan

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Thanks, Dan. I am at the 4th step and this is the code I am using:

proc sgplot data=whatever;

vbarparm category=subjid response=tot / group=Visit;

xaxis discreteorder=data label='Subject';

yaxis label='Total Dose';

run;

I am getting a graph similar to using the grouporder option that I was using previously. Can you please let me know what I am missing?

Thanks,

Vamsi  DanH_sas
SAS Super FREQ

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Can you PROC PRINT your data and verify that the groups within each bar are in order? You might need to specify GROUPORDER=ASCENDING on the VBARPARM as well. Let me know what you find.

Thanks!
Dan

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

The PROC PRINT shows the data are in the correct order. The grouporder=ascending does not add anything.

Thanks,

Vamsi  DanH_sas
SAS Super FREQ

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Since your data is in the correct order, try GROUPORDER=DATA and see if that works for you.

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Dan,

Thank you so much. The issue was to sort it by only the tot_height and then it works.

Thanks,

Vamsi

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

Dan,

How can I add a data label on top of a few stacked bars. For example, I want to add a label above all 'male' subjects.

data dlabel;

set test;

if male='Y' then dlabel="*";

else dlabel=" ";

run;

I tried using the datalabel=dlabel option in my vbarparm statement as you suggested in another post.

It does not work for me. I would appreciate any help.

Thanks,

Vamsi  DanH_sas
SAS Super FREQ

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

That example also needed GROUPDISPLAY=CLUSTER. I have now corrected that example. Thanks for bringing it to my attention. Since you need this for stacked bars, you can use a TEXT plot overlay on your VBARPARM to add the labels at the top. Here is a simple example:

``````/* The standard bar calculations using the group variable*/
proc summary data=sashelp.class nway;
class age sex;
var weight;
output out=temp sum=sumwgt;
run;

/* Find the top of the bars */
proc summary data=sashelp.class nway;
class age;
var weight;
output out=labelpos sum=pos;
run;

data class;
merge temp labelpos (keep=age pos);
by age;
if age < 14 then label="Young";
else label="Old";
run;

proc sgplot data=class;
vbarparm category=age response=sumwgt / group=sex;
text x=age y=pos text=label / position=top;
run;``````

Hope this helps!

Dan

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

I already have a group. So my code looks like this:

proc sgplot data=test;

vbarparm category=subjid repsonse=tot /*total dose at each visit*/

/ group=visit grouporder=ascending datalabel=dlabel;

xaxis discreteorder=data label='Subject';

yaxis label = 'Total Dose' values=(0 to 5000 by 1000) offsetmin=0;

run;

Thanks,

Vamsi

## Re: Stacked Box Plot sorted by Y-axis variable and an internal sort order for each stack

It worked. I did not notice the y=bar_ht in the text statement. Thank you.

Discussion stats
• 12 replies
• 1984 views
• 1 like
• 3 in conversation