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 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 810 views
  • 1 like
  • 2 in conversation