Data visualization with SAS programming

Grouped LEGEND

Reply
Respected Advisor
Posts: 3,776

Grouped LEGEND

I want to make VBAR that looks something like this
img0.png
but I want a grouped legend one for each SEX something like this...
img1.png
But I want bars to bars to all be the same size.
This is the code I used to get the charts show above.  I don't have to use any of this if there is easy way to make the grouped legend.  That is really all I need.  Keep in mind that I don't know what I'm doing.
%let where=not(sex eq 'F' and age gt 12);
proc sgplot data=sashelp.class;
   where &where;
   vbar sex / stat=mean response=weight group=age groupdisplay=cluster name='a';
  
keylegend 'a';
  
run;
  
quit;




proc summary data=sashelp.class nway;
  
where &where;
   class sex age;
   output out=class(drop=_Smiley Happy mean(weight)=;
   run;
proc transpose out=class1;
   by sex;
   var age weight;
   run;
proc transpose out=class2 delim=_;
   var col:;
   id sex _name_;
   run;
data class2;
   set class2;
   retain F 'Female' M 'Male' one 1;
  
run;
data class3;
   update class2(obs=0) class2;
   by one;
   output;
  
call missing(of f_weight m_weight);
   run;


proc sgplot;
  
vbarparm category=F response=f_weight / group=f_age name='F';
  
vbarparm category=M response=m_weight / group=m_age name='M';
  
keylegend 'F' / title='Female';
  
keylegend 'M' / title='Male';
  
xaxis display=(nolabel);
   run;
  
quit;

SAS Super FREQ
Posts: 1,081

Re: Grouped LEGEND

One quick way is to set clusterwidth for the Female plot.  But there may be other (more robust) ways to do this without having to summarize the data yourself.

proc sgplot;

   vbarparm category=F response=f_weight / group=f_age name='F' clusterwidth=0.25;

   vbarparm category=M response=m_weight / group=m_age name='M';

   keylegend 'F' / title='Female';

   keylegend 'M' / title='Male';

   xaxis display=(nolabel);

   run;

   quit;

Fig_8_5_EllipseParm_Icon_33.png

Respected Advisor
Posts: 3,776

Re: Grouped LEGEND

Hi thanks.  How did you get .25?  Can that be calculated?  I want this to be hands free.  In my program there might be more groups (sex) with a varying number of levels (age) at each level of sex.  All reasonable of course.

I don't mind doing the summary but I would like to see a more robust way to get the Legend's.

SAS Super FREQ
Posts: 3,420

Re: Grouped LEGEND

Try this for obtaining the clusterwidth: Use PROC FREQ or SQL to find the maximum number of age categories (6) in any age category. If you use 1/6 as the clusterwidth, then 6 bars will fit between the Female and Male tick marks. (Verify this.)  However, if both Female and Male have the maximun number of categories, then the Female bars will abut the Male bars. You don't want this, so to ensure that there is space between the bars, make the clusterwidth smaller than 1/6.   I believe that what Sanjy did was to add "two bars width" worth of space between the categories. Thus his width was 1/8.  If space is an issue, 1/7 (one bar's width) is probably sufficient.

SAS Super FREQ
Posts: 1,081

Re: Grouped LEGEND


Compute the maximum number of non missing values for f_weight (=c1) and m_weight (=c2).  Max is the largest of these. Set the cluster width of each plot to 0.85*cn/max.  This should scale to any number of columns.

085 is the default cluster width.  You can use any value up to 1.0.

data _null_;
  retain c1 0 c2 0;
  set class3 end=last;

  if f_weight then c1=c1+1;
  if m_weight then c2=c2+1;

  if last then do;
    max=max(c1, c2);
    call symput("cw1", 0.85*c1/max);
    call symput("cw2", 0.85*c2/max);
  end;
  run;

proc sgplot data=class3;
   vbarparm category=F response=f_weight / group=f_age name='F' clusterwidth=&cw1;
   vbarparm category=M response=m_weight / group=m_age name='M' clusterwidth=&cw2;
   keylegend 'F' / title='Female';
   keylegend 'M' / title='Male';
   xaxis display=(nolabel);
   run;

SAS Super FREQ
Posts: 1,081

Re: Grouped LEGEND

To remove the warnings in the log about bad data for BARCHARTPARM, if f_weight is missing, set the corresponding value for f = missing.

Remove Y axis label.

data class4;
  retain c1 0 c2 0;
  set class3 end=last;

  if f_weight then c1+1; else f='';
  if m_weight then c2+1; else m='';

  if last then do;
    max=max(c1, c2);
    call symput("cw1", 0.85*c1/max);
    call symput("cw2", 0.85*c2/max);
  end;
  run;

proc sgplot data=class4;
   vbarparm category=F response=f_weight / group=f_age name='F' clusterwidth=&cw1;
   vbarparm category=M response=m_weight / group=m_age name='M' clusterwidth=&cw2;
   keylegend 'F' / title='Female';
   keylegend 'M' / title='Male';
   xaxis display=(nolabel);

   yaxis display=(nolabel);
   run;

Respected Advisor
Posts: 3,776

Re: Grouped LEGEND

Hi yes.  Using the info that Rick provided I came us with something very similar to your code.  Thanks to both you and Rick.

Ask a Question
Discussion stats
  • 6 replies
  • 370 views
  • 9 likes
  • 3 in conversation