goptions reset=all target=ps300 ftext=swissb
rotate=landscape gsfname=fred gsfmode=replace;
/* Define the macro with parameters for input data set and */
/* survey month and year */
%macro stdplot(indsn,monyear);
proc format;
/* Define format for coding the response values */
value respfmt 1 = '1=Poor'
2 = '2=Fair'
3 = '3=Good'
4 = '4=Very Good'
5 = '5=Excellent';
/* Define format for Marital Status category */
value $ marfmt 'S' = 'Single'
'M' = 'Married'
'D' = 'Divorced'
'W' = 'Widowed';
/* Define format for Annual Income category */
value incfmt 0 = '< $25,000'
1 = '$25,000-$49,999'
2 = '$50,000-$74,999'
3 = '$75,000-$99,999'
4 = '$100,000 +';
/* Define format for Sex category */
value $ sexfmt 'F' = 'Female'
'M' = 'Male';
/* Define ranges for Age Group category */
value agefmt 0 - 24 = 'Under 25'
25 - 34 = '25 to 34'
35 - 44 = '35 to 44'
45 - 64 = '45 to 64'
65 - high = '65 or older';
run;
/* Read in raw data and define grouping variables */
data survey;
infile "~sasjzr/obs/issue15/&indsn..dat";
length category $20;
input sex $ 1 marital $ 3 age 5-6 income 8 overall 10;
category=put(sex,$sexfmt.); group=1; output;
category=put(marital,$marfmt.); group=2; output;
category=put(age,agefmt.); group=3; output;
category=put(income,incfmt.); group=4; output;
run;
/* Sort the data by the CATEGORY variable before summarizing */
/* with PROC FREQ. */
proc sort data=survey;
by category;
run;
/* Use the FREQ procedure to obtain the frequency count and */
/* percentage of respondents in each category of each group */
/* so that a customized table of values can be annotated onto */
/* the plot. */
proc freq data=survey noprint;
tables category*group / out=freqs;
run;
/* Define an ANNOTATE data set to draw and fill a table */
/* containing the frequency count and percentage of */
/* respondents in each category of each group. */
data anno1;
set freqs;
length function style color $8 xc text $15;
/* Draw the outline of the table and fill with grey scale */
/* shading, place headings on the table columns and place */
/* group labels next to each category. These elements need */
/* only be drawn once, so they are defined at the beginning */
/* of the data step. */
if _n_=1 then do;
/* X values reflect a percentage of the axis area, y values */
/* reflect a percentage of the whole graphics output area */
xsys='1'; ysys='3';
/* Draw shaded background of table */
x=0; y=80; function='move'; output;
x=100; y=100; function='bar'; line=0; style='solid';
color='grayee'; output;
/* Draw table outline */
x=0; y=80; function='move'; output;
x=100; y=100; function='bar'; style='empty';
color='black'; output;
/* Draw center line to divide frequency and percentage values */
function='move'; x=100; y=90; output;
function='draw'; line=1; x=0; output;
/* Place labels to the left of each group of categories. Note */
/* that the text is positioned just to the left of the first */
/* category value in each group by setting XSYS to '2' for */
/* data values, hardcoding the XC variable values for that */
/* category and assigning the horizontal location with a */
/* Y variable value of 12.5 percent. */
xsys='2';
function='label';
position='4'; size=1;
y=12.5; angle=90; style='swissb';
xc='Female';
text='Sex:'; output;
xc='Single';
text='Marital Status:'; output;
xc='Under 25';
text='Age Group:'; output;
xc='< $25,000';
text='Annual Income:'; output;
/* Place labels at top of table */
xsys='1';
function='label'; position='5';
x=2; y=85; angle=90; style='swissb'; size=.75;
text='FREQ:'; output;
y=95; text='PCT:'; output;
function='move'; x=4; y=80; output;
function='draw'; y=100; output;
end;
/* Place values in table */
xsys='2'; ysys='3';
function='label';
style='swissb'; size=1;
xc=category;
y=85; position='5'; angle=90;
text=left(put(count,4.));
output;
position='4';
y=98; text=left(put(count/200,percent11.2));
output;
run;
/* Run the MEANS procedure to obtain an overall mean response */
/* value across the survey sample of customers. This value */
/* will be used to display and label a reference line at the */
/* mean. */
proc means data=survey mean noprint;
var overall;
output out=allmean mean=mean;
run;
/* Combine the original data with the output data set from */
/* PROC MEANS, and define a macro variable that contains the */
/* overall mean value. */
data all;
set survey;
if _n_=1 then do;
set allmean;
call symput('mean',mean);
end;
run;
/* Create a second ANNOTATE data set to label the reference */
/* line that reflects the overall mean value. */
data anno2;
length text $20;
xsys='1'; ysys='2';
x=100; y=&mean; position='8';
function='label'; angle=90;
text='Overall Mean: '||left(put(&mean,5.2));
output;
run;
/* Define SYMBOL statements that to request a standard */
/* deviation interpolation be applied to data from each of */
/* the four groups. The STDMJT interpolation method produces */
/* a plot with The fifth symbol definition is used for */
/* producing a null plot with the PLOT2 statement. */
symbol1 i=stdmjt c=BLACK v=none;
symbol2 i=stdmjt c=BLACK v=none;
symbol3 i=stdmjt c=BLACK v=none;
symbol4 i=stdmjt c=BLACK v=none;
symbol5 i=none v=none;
/* Specify titles and footnote */
title1 h=1.5 a=90 "Jude's Javas, Store #1";
title2 h=1.5 a=90 "Overall Selection of Coffees";
title3 h=1.5 a=90 "Customer Survey &monyear";
/* Define AXIS statements to specify the attributes to be */
/* associated with the vertical and horizontal axes. The */
/* ORDER= list for the horizontal axis explicitly lists the */
/* category variable values in the appropriate order, with */
/* blank spaces inserted between the groups of values, while */
/* the ORDER= list for the vertical axis relies on a user- */
/* written format to provide the desired tick mark values. */
axis1 order=(
/* SEX */
'Female' 'Male' ' '
/* AGE GROUP */
'Under 25' '25 to 34' '35 to 44' '45 to 64' '65 or older' ' '
/* MARITAL STATUS */
'Single' 'Married' 'Divorced' 'Widowed' ' '
/* ANNUAL INCOME */
'< $25,000' '$25,000-$49,999' '$50,000-$74,999' '$75,000-$99,999'
'$100,000 +')
label=none major=none style=0 length=75 pct
offset=(5 pct,5 pct) value=(a=90 r=0);
axis2 order=1 to 5 label=none minor=none origin=(15,25 pct)
length=55 pct offset=(5,5) pct value=(h=.9 a=90);
/* Finally, produce the graph. A predefined format is used to */
/* convert the coded survey values into their associated */
/* response levels along the vertical axis. The AUTOVREF and */
/* LVREF= options on the PLOT statement request dotted */
/* reference lines at each major tick mark along the vertical */
/* axis. One ANNOTATE data set is specified on the PLOT */
/* statement, and the other is specified on the PLOT2 */
/* statement. In this case, it doesn't matter which annotate */
/* data set is specified on which plot statement. Although a */
/* legend is produced automatically when a Y*X=Z plot request */
/* format is used, it would not be useful on this particular */
/* graph. The legend is therefore suppressed with the */
/* NOLEGEND option. */
/* */
/* The PLOT2 statement and the associated SYMBOL definition */
/* request that no plot line be drawn on the graph. The plot */
/* request is necessary to allow other options on the PLOT2 */
/* statement to be utilized. The VREF= and LVREF= options on */
/* the PLOT2 statement are used to produce a dashed reference */
/* line at the overall mean value. The plot request on the */
/* PLOT2 statement could also be used to produce a horizontal */
/* line at the mean value as long as an appropriate SYMBOL */
/* definition is specified with INTERPOL=JOIN and LINE= for */
/* the desired linestyle. The resulting line would not extend */
/* across any offsets that were requested on that axis, */
/* therefore this example chose to use the VREF= option */
/* instead. Because the axes produced by the PLOT2 statement */
/* are not needed, the NOAXES option is used to suppress them */
/* from being drawn. */
proc gplot data=all;
note a=90 move=(97,2) pct h=.9
"200 Customers surveyed. Plot reflects MEAN +/- 2
STANDARD DEVIATIONS.";
format overall respfmt.;
plot overall*category=group / anno=anno1 haxis=axis1 vaxis=axis2
nolegend lvref=34 autovref;
plot2 mean*category=5 / anno=anno2 haxis=axis1 vaxis=axis2
noaxes vref=&mean lvref=2;
run;
quit;
%mend stdplot;
/* Invoke the macro with parameters */
%stdplot(jan95,January 1995);