BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Vamsi_77
Fluorite | Level 6

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
Vamsi_77
Fluorite | Level 6

Dan,

 

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

 

Thanks,

Vamsi

View solution in original post

12 REPLIES 12
ballardw
Super User

@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.

Vamsi_77
Fluorite | Level 6

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

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

Vamsi_77
Fluorite | Level 6

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

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

Vamsi_77
Fluorite | Level 6

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

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

Vamsi_77
Fluorite | Level 6

Dan,

 

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

 

Thanks,

Vamsi

Vamsi_77
Fluorite | Level 6

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.

https://communities.sas.com/t5/Graphics-Programming/Adding-a-significance-star-in-a-bar-chart/m-p/33...

 

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

 

Thanks,

Vamsi

DanH_sas
SAS Super FREQ

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;

/* merge what is needed, and add your labels */
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

Vamsi_77
Fluorite | Level 6

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

 

Vamsi_77
Fluorite | Level 6

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

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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