BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Barkat
Pyrite | Level 9

I have a table 'have' with the following columns.

ID

AgeGroup: 18-24, 25-29, 30-34, 35-39, 40-44, 45-49, 50-59, 60+

Gender: F, M

Race: Black, White, Hispanic, Asian, Hawiian/AmIndian, Other

Vaccination Status: Full, Partial, None

 

Sample table

 

data have;
  input ID AgeGroup $ Gender $ Race $ VaccinStatus $;
datalines;
100 18-24 F Asian Full
101 25-29 M Hispanic Full
102 18-24 F White None
103 55+ M White Full
104 40-44 F Hispanic None
105 18-24 M Asian Full
106 50-54 M White Full
107 30-34 M Asian None
108 18-24 M Hispanic Full
109 40-44 M White Partial
110 45-49 M Other Full
111 55+ F Asian Full
112 40-44 M Other Partial
113 35-39 F Hawaiian Partial
114 25-29 M Asian Full
115 40-44 M Hawaiian Full
116 30-34 F White Partial
117 40-44 F White Full
118 45-49 F Asian Full
119 18-24 M Hispanic Full
120 25-29 F White None
121 55+ M White Full
122 45-49 F Hispanic None
123 50-54 M Asian Full
124 30-34 M White Full
125 40-44 M Asian None
126 18-24 M Hispanic Full
127 55+ M White Partial
128 35-39 M Other Full
129 50-54 F Asian Full
130 18-24 M Other Partial
131 35-39 F Hawaiian Partial
132 45-49 M Asian Full
133 40-44 M Hawaiian Full
134 30-34 F White Partial
135 18-24 F White Full
run;

 

 

 

I would like to create a 100% stacked bar chart where AgeGroup with categories, Gender with categories, Race with categories will be on the X-axis and Vaccination Status will be on the Y-axis.

Barkat_1-1722974418378.png

 

 

I tried the following code but failed.

 

Proc SGPLOT data=Have pctlevel=group;
Vbar AgeGroup, Gender, Race / group = VaccinStatus Stat=percent;
Title 'Vaccination Status by Age, gender and race';
Xaxis discreteorder=data;
YAXIS grid values=(0 to 100 by 10);
run;
quit;

 

Error Log:

NOTE: Writing HTML5(EGHTML) Body file: EGHTML
27
28 Proc SGPLOT data=Have pctlevel=group;
29 Vbar AgeGroup, Gender, Race / group = VaccinStatus Stat=percent;
_
22
200
ERROR 22-322: Syntax error, expecting one of the following: ;, /.
ERROR 200-322: The symbol is not recognized and will be ignored.
30 Title 'Vaccination Status by Age, gender and race';
31 Xaxis discreteorder=data;
32 YAXIS grid values=(0 to 100 by 10);
33 run;

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

See it this gives you a starting point:

 

/* this is one way to carfully get values
   that total percentages to 100 by groups
*/
proc tabulate data=have out=work.tabsummary;
   class agegroup gender race Vaccinstatus;
   tables (agegroup gender race)*Vaccinstatus ,
          pctn<Vaccinstatus>
   ;
run;

data work.toplot;
   set work.tabsummary ;
   length axisgroup  axisvalue $ 10;
   if _type_= '1001' then do;
      axisgroup= 'Age Group';
      axisvalue= AgeGroup;
      value = PctN_1000;
   end;
   if _type_= '0101' then do;
      axisgroup= 'Gender';
      axisvalue = Gender;
      value = PctN_0100;
   end;
   if _type_= '0011' then do;
      axisgroup= 'Race';
      axisvalue = race;
      value = PctN_0010;
   end;
run;

proc sgpanel data=work.toplot;
  panelby axisgroup 
         /uniscale=row 
         layout=columnlattice
/*         colheaderpos=bottom*/
         novarname
/*         noheaderborder*/
/*         noborder */
         proportional 
  ;
  vbar axisvalue/response=value group=Vaccinstatus ;
  colaxis label=' ';
run;

The Proc tabulate as I have in the comments is to get the percentages such that the vaccine status percentages are calculated and total to 100 with the report group. This is not the only way but is relatively easy to expand on the number of report groups.

The data step gets a single X-axis variable and assigns the values to a single variable. Because of the way the output data set is created it also gets a single value for the different types of percentages.

This uses options available in SGPANEL to create subgraphs for each of the report groups and some options to get sort of close to your shown desired appearance. You can experiment some by removing the comment characters around some of the options in the Panelby statement.

 

 

View solution in original post

4 REPLIES 4
ballardw
Super User

One of the requirements across most of the graphing procedures is a single X-axis variable.

So likely need to do some data reshaping.

Can you provide some example data in the form of a working data step so we can work through to a solution using step that follow your data? If we have to make up data it is quite likely not going to resemble yours and so provided steps would be quite likely not be a workable solution for you.

 

Note; you should include the log with the errors you proc attempt threw. Such as

89   proc sgplot data=work.class;
90      vbar  age, sex / stat=percent;
                 -
                 22
                 200
ERROR 22-322: Syntax error, expecting one of the following: ;, /.
ERROR 200-322: The symbol is not recognized and will be ignored.
91   run;

Which indicates the comma (or anything except a space or / or ; ) is going to be invalid.

Other likely attempts will get you errors like "The same category variable must be used for summarized plots"

Barkat
Pyrite | Level 9
Thanks! Sample data and error log added in the original question
ballardw
Super User

See it this gives you a starting point:

 

/* this is one way to carfully get values
   that total percentages to 100 by groups
*/
proc tabulate data=have out=work.tabsummary;
   class agegroup gender race Vaccinstatus;
   tables (agegroup gender race)*Vaccinstatus ,
          pctn<Vaccinstatus>
   ;
run;

data work.toplot;
   set work.tabsummary ;
   length axisgroup  axisvalue $ 10;
   if _type_= '1001' then do;
      axisgroup= 'Age Group';
      axisvalue= AgeGroup;
      value = PctN_1000;
   end;
   if _type_= '0101' then do;
      axisgroup= 'Gender';
      axisvalue = Gender;
      value = PctN_0100;
   end;
   if _type_= '0011' then do;
      axisgroup= 'Race';
      axisvalue = race;
      value = PctN_0010;
   end;
run;

proc sgpanel data=work.toplot;
  panelby axisgroup 
         /uniscale=row 
         layout=columnlattice
/*         colheaderpos=bottom*/
         novarname
/*         noheaderborder*/
/*         noborder */
         proportional 
  ;
  vbar axisvalue/response=value group=Vaccinstatus ;
  colaxis label=' ';
run;

The Proc tabulate as I have in the comments is to get the percentages such that the vaccine status percentages are calculated and total to 100 with the report group. This is not the only way but is relatively easy to expand on the number of report groups.

The data step gets a single X-axis variable and assigns the values to a single variable. Because of the way the output data set is created it also gets a single value for the different types of percentages.

This uses options available in SGPANEL to create subgraphs for each of the report groups and some options to get sort of close to your shown desired appearance. You can experiment some by removing the comment characters around some of the options in the Panelby statement.

 

 

ChrisNZ
Tourmaline | Level 20

You can't make up syntax that does not exist.

 

Your graph is straight forward with proc gchart and more difficult with ods graphics (no doubt more advanced users can fix my attempts).

 

ods _all_ close;
ods pdf file="%sysfunc(pathname(WORK))/dummy.pdf";
ods output CrossTabFreqs=CROSSTABFREQS;
proc freq data=HAVE;  ******* CALCULATE PERCENTAGES HERE FOR NOW, MAYBE IN GRAPHS LATER ************;
  table (AGEGROUP GENDER RACE) * VACCINSTATUS  ;
run;
ods output close;
ods pdf close;

data PLOT;
  set CROSSTABFREQS;
  where _TYPE_='11';
  if AGEGROUP ne ' ' then AXISGROUP = 'Age Group'; 
  if GENDER   ne ' ' then AXISGROUP = 'Gender   ';
  if RACE     ne ' ' then AXISGROUP = 'Race     ';
  AXISVALUE = coalescec(AGEGROUP, GENDER, RACE);
run; 

then

proc sgplot data=PLOT; ********************** NO AXIS GROUPING ********************************;
  vbar AXISVALUE / response=ROWPERCENT group=VACCINSTATUS stat=SUM groupdisplay=stack ;
  xaxis display=(nolabel) discreteorder=data ;
  yaxis display=(nolabel) grid values=(0 to 100 by 10); 
run;

proc sgpanel data=PLOT; **************** TOO MANY BARS DESPITE nozerobars OPTION **************;
  panelby AXISGROUP / onepanel layout=columnlattice colheaderpos=bottom noborder novarname; 
  vbar AXISVALUE / group=VACCINSTATUS response=ROWPERCENT stat=sum nozerobars groupdisplay=stack grouporder=data ;
  colaxis display=(nolabel);   
  rowaxis display=(nolabel) values=(0 to 100 by 10) ;
run;

axis1 label=none;
goptions dev=png xpixels=800 ypixels=600;
proc gchart data=PLOT;   ***************** PERFECT ************************************************;
  vbar AXISVALUE / subgroup=VACCINSTATUS sumvar=ROWPERCENT group=AXISGROUP nozero raxis=axis1 maxis=axis gaxis=axis1;
  run;
quit;
   

ChrisNZ_0-1723009279472.png

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 4 replies
  • 401 views
  • 2 likes
  • 3 in conversation