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!
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.
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.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.