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);