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 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
  • 12 replies
  • 1463 views
  • 4 likes
  • 4 in conversation