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

Hello - I know questions like mine have been asked before, but I wasn't able to find an answer that I could adapt to my situation. I would like to create a single bar chart with individual bars for several variables in my dataset, where the values for each variable are either 0 or 1 for each record in the dataset.

 

I created a series of binary (0/1) variables from questions on a survey where respondents could select one more options (e.g. bn_option1, bn_option2, ...) . Now I'd like to create bar charts for the % of '1's for each option (binary variable) of the corresponding question. One bar chart per question with as many bars as there were originally options. Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User
data have;
input Id  Option1 Option2 Option3 Option4;
cards;
1   0   0   0   1
2   0   0   1   0
3   0   1   0   1
4   1   0   1   1
;
run;

ods select none;
ods output summary=summary_results;
proc means data=have stackods mean;
var option1-option4;
run;
ods select all;

proc sgplot data=summary_results;
vbarparm response=mean category=variable;
format mean percent12.1;
label mean = 'Response';
run;

View solution in original post

12 REPLIES 12
PaigeMiller
Diamond | Level 26

First of all, are you looking for help doing this in SAS?

 

I created a series of binary (0/1) variables from questions on a survey where respondents could select one more options (e.g. bn_option1, bn_option2, ...) . Now I'd like to create bar charts for the % of '1's for each option (binary variable) of the corresponding question. One bar chart per question with as many bars as there were originally options.

Please show us a portion of this data, provided as working SAS data step code (Examples and Instructions)

--
Paige Miller
NeilH
Obsidian | Level 7

Yes, Paige, I am.

Ksharp
Super User

That would be better to demonstrate your question by posing some data and the picture you want to see.

 

data have;
call streaminit(123);
array x{*} opt1-opt6;
do id=1 to 100;
do i=1 to dim(x);
 x{i}=rand('bern',i/10);
end;
output;
end;
drop i;
run;




proc transpose data=have out=want;
by id;
var opt:;
run;
proc sgplot data=want pctlevel=group;
vbar _name_/group=col1 stat=percent ;
run;

Ksharp_0-1714445711381.png

 

NeilH
Obsidian | Level 7

Thank you. Here's sample data and a desired bar chart (without axis labeling).

 

IdOption1Option2Option3Option4
10001
20010
30101
41011

 

NeilH_0-1714485005391.png

 

NeilH
Obsidian | Level 7
Your solution works just about perfectly for me. Is it possible just to display the % of 1s in the bars rather than having them as stacked bars that total 100%?
Reeza
Super User
data have;
input Id  Option1 Option2 Option3 Option4;
cards;
1   0   0   0   1
2   0   0   1   0
3   0   1   0   1
4   1   0   1   1
;
run;

ods select none;
ods output summary=summary_results;
proc means data=have stackods mean;
var option1-option4;
run;
ods select all;

proc sgplot data=summary_results;
vbarparm response=mean category=variable;
format mean percent12.1;
label mean = 'Response';
run;
NeilH
Obsidian | Level 7

Thank you. That's perfect!

NeilH
Obsidian | Level 7

Hi Reeza,

 

Your solution to my bar chart question was elegant and works. One minor additional question. Is it possible to display the labels I have for options1-options4 for the x-axis labeling rather than the variable names?

 

 

My code based on your answer is what I have below. Both q_7760_bn1 and q7760_bn2 have labels associated with them from the original dataset (ips.allvars3) that I see with a proc contents on summary_results.

Thanks.

 

NeilH_1-1714493531383.png

 

ods select none;
ods output summary=summary_results;
proc means data=ips.allvars3 stackods mean;
var q7760_bn1 q7760_bn2;
run;
ods select all;

 

proc sgplot data=summary_results;
vbarparm response=mean category=variable;
format mean percent12.1;
label mean = 'Response';
run;

Reeza
Super User

Change category= variable from variable to label, in the PROC SGPLOT code.

 

data have;
input Id  Option1 Option2 Option3 Option4;
label option1 = 'Question #99' option2 = 'Random Text #2' option3 = 'Demoe' option4 = 'House';
cards;
1   0   0   0   1
2   0   0   1   0
3   0   1   0   1
4   1   0   1   1
;
run;

ods select none;
ods output summary=summary_results;
proc means data=have stackods mean;
var option1-option4;
run;
ods select all;

proc sgplot data=summary_results;
vbarparm response=mean category=label;
format mean percent12.1;
label mean = 'Response';
run;

@NeilH wrote:

Hi Reeza,

 

Your solution to my bar chart question was elegant and works. One minor additional question. Is it possible to display the labels I have for options1-options4 for the x-axis labeling rather than the variable names?

 

 

My code based on your answer is what I have below. Both q_7760_bn1 and q7760_bn2 have labels associated with them from the original dataset (ips.allvars3) that I see with a proc contents on summary_results.

Thanks.

 

NeilH_1-1714493531383.png

 

ods select none;
ods output summary=summary_results;
proc means data=ips.allvars3 stackods mean;
var q7760_bn1 q7760_bn2;
run;
ods select all;

 

proc sgplot data=summary_results;
vbarparm response=mean category=variable;
format mean percent12.1;
label mean = 'Response';
run;


 

 

NeilH
Obsidian | Level 7

Worked perfectly, Reeza!

 

My one issue with the current labels I have, is that  a few of them are quite long and crowd out the chart. I'll research this, but if you know of a word wrap option that can be applied to the labels in sgplot or an alternative, that would be great. I think I see how to add a line break in the label itself when it's set - (*ESC*){unicode '000a'x}. But it's not appearing as I'd hope in the chart itself. Below is an example of a lengthy label without a newline in it. The chart displays perfectly for shorter labels.

 

NeilH_0-1714574283094.png

 

 

Reeza
Super User

FITPOLICY and SPLITCHAR on XAXIS statement.

 

data have;
input Id  Option1 Option2 Option3 Option4;
label option1 = 'Question really long text # to force split 99' option2 = 'Random Text with #another random split' option3 = 'Demoe' option4 = 'House';
cards;
1   0   0   0   1
2   0   0   1   0
3   0   1   0   1
4   1   0   1   1
;
run;

ods select none;
ods output summary=summary_results;
proc means data=have stackods mean;
var option1-option4;
run;
ods select all;

proc sgplot data=summary_results;
vbarparm response=mean category=label;
format mean percent12.1;
label mean = 'Response';
xaxis fitpolicy=split splitchar='#';
run;

@NeilH wrote:

Worked perfectly, Reeza!

 

My one issue with the current labels I have, is that  a few of them are quite long and crowd out the chart. I'll research this, but if you know of a word wrap option that can be applied to the labels in sgplot or an alternative, that would be great. I think I see how to add a line break in the label itself when it's set - (*ESC*){unicode '000a'x}. But it's not appearing as I'd hope in the chart itself. Below is an example of a lengthy label without a newline in it. The chart displays perfectly for shorter labels.

 

NeilH_0-1714574283094.png

 

 


 

NeilH
Obsidian | Level 7
Perfect! Thank you.

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 12 replies
  • 2108 views
  • 4 likes
  • 4 in conversation