BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
xinyao
Fluorite | Level 6
input age $5. group count PERCENT;
datalines;
<1  	0	29	100
1-4	    0	50	100
5-19	0	284	98
20-44	0	4285	93
45-54	0	1930	83
55-64	0	1570	76
65-74	0	728	70
75-84	0	290	68
85+	    0	156	74
1-4	    1	6	2
20-44	1	306	7
45-54	1	388	17
55-64	1	487	24
65-74	1	311	30
75-84	1	139	32
85+ 	1	56	26
;
run;
proc format;
value $afmt 
'<1' ='1'
'1-4'= '2'
'5-19'='3'
'20-44'='4'
'45-54'='5'
'55-64'='6'
'65-74'='7'
'75-84'='8'
'85+'='9'
;

 value $ a_fmt
 '1' = '<1'
 '2' ='1-4'
 '3' = '5-19'
'4' = '20-44'
'5' = '45-54'
'6' = '55-64'
'7' = '65-74'
'8' = '75-84'
'9' = '85+';
 run;

                                                                                                   
ods graphics on / width=10in height=9 in;
title "100% Stacked Bar Chart Ordered by Percentages";
proc sgplot data=one;
vbar age / response=Percent group= group 
              grouporder=data groupdisplay=stack  seglabel ;  
 *seglabel segment labels;
/*xaxis discreteorder=data;*/
			   format age $a_fmt.;
yaxis grid values=(0 to 100 by 10) label="Percentage of Total with Group";
run;

How can I  show the bar chart in order: <1, 1-4, 5-19, 20-44, 45-54,....

 

Thank you!

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Instead of creating character variables with values like "<1" leave them as original ages and make a custom format to display them, or make them specific numeric values with appropriate format that displays the values as needed.

One of many ways possible:

proc format;
invalue afmt 
'<1'   =1
'1-4'  =2
'5-19' =3
'20-44'=4
'45-54'=5
'55-64'=6
'65-74'=7
'75-84'=8
'85+'  =9
;
value a_fmt
1 = '  <1'
2 = ' 1-4'
3 = ' 5-19'
4 = '20-44'
5 = '45-54'
6 = '55-64'
7 = '65-74'
8 = '75-84'
9 = '85+';
run;

data have;
input age afmt. group count PERCENT;
datalines;
<1  	0	29	100
1-4	    0	50	100
5-19	0	284	98
20-44	0	4285	93
45-54	0	1930	83
55-64	0	1570	76
65-74	0	728	70
75-84	0	290	68
85+	    0	156	74
1-4	    1	6	2
20-44	1	306	7
45-54	1	388	17
55-64	1	487	24
65-74	1	311	30
75-84	1	139	32
85+ 	1	56	26
;

proc sgplot data=have;
vbar age / response=Percent group= group 
              grouporder=data groupdisplay=stack  seglabel ;  
 *seglabel segment labels;
/*xaxis discreteorder=data;*/
format age a_fmt.;
yaxis grid values=(0 to 100 by 10) label="Percentage of Total with Group";
run;

This uses a custom informat to read the age group text values into numeric values that order as desired.

Also in many respects the formatted values are used and it is a good idea to pay attention to the sort order of the formatted values. You will find that '<1' is alphabetically after '1', similarly '5' is after '10' because the first characters are compared for ordering. So create an ' 5' instead of '5' to get the sort order correct.

 

Of course if you summarized some other data that had age as a numeric to create the data set one, then likely you should leave the values as numeric and use a custom numeric format to create the grouping values. The analysis and graphing procedures will generally honor formats used  to create groups of values. The raw data likely could have been used in this case.

View solution in original post

2 REPLIES 2
ballardw
Super User

Instead of creating character variables with values like "<1" leave them as original ages and make a custom format to display them, or make them specific numeric values with appropriate format that displays the values as needed.

One of many ways possible:

proc format;
invalue afmt 
'<1'   =1
'1-4'  =2
'5-19' =3
'20-44'=4
'45-54'=5
'55-64'=6
'65-74'=7
'75-84'=8
'85+'  =9
;
value a_fmt
1 = '  <1'
2 = ' 1-4'
3 = ' 5-19'
4 = '20-44'
5 = '45-54'
6 = '55-64'
7 = '65-74'
8 = '75-84'
9 = '85+';
run;

data have;
input age afmt. group count PERCENT;
datalines;
<1  	0	29	100
1-4	    0	50	100
5-19	0	284	98
20-44	0	4285	93
45-54	0	1930	83
55-64	0	1570	76
65-74	0	728	70
75-84	0	290	68
85+	    0	156	74
1-4	    1	6	2
20-44	1	306	7
45-54	1	388	17
55-64	1	487	24
65-74	1	311	30
75-84	1	139	32
85+ 	1	56	26
;

proc sgplot data=have;
vbar age / response=Percent group= group 
              grouporder=data groupdisplay=stack  seglabel ;  
 *seglabel segment labels;
/*xaxis discreteorder=data;*/
format age a_fmt.;
yaxis grid values=(0 to 100 by 10) label="Percentage of Total with Group";
run;

This uses a custom informat to read the age group text values into numeric values that order as desired.

Also in many respects the formatted values are used and it is a good idea to pay attention to the sort order of the formatted values. You will find that '<1' is alphabetically after '1', similarly '5' is after '10' because the first characters are compared for ordering. So create an ' 5' instead of '5' to get the sort order correct.

 

Of course if you summarized some other data that had age as a numeric to create the data set one, then likely you should leave the values as numeric and use a custom numeric format to create the grouping values. The analysis and graphing procedures will generally honor formats used  to create groups of values. The raw data likely could have been used in this case.

xinyao
Fluorite | Level 6
Thank you so much! it works well!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 2 replies
  • 530 views
  • 1 like
  • 2 in conversation