*
;
/***************************************************************/
/* DRAWLAB: places text labels with minimum and maximum */
/* values at each end of the axis */
/* ARGUMENT VALUE */
/* -------- ----- */
/* Y: Y coordinate (position of axis) */
/* B: minimum value */
/* T: maximum value */
/* */
/* REQUIREMENTS: Use in PAIRWISE macro after the */
/* GRAPH('CLEAR') and before the GRAPH('UPDATE')*/
/* function calls */
/* */
/* Requires minimum and maximum values */
/* compatible with BEST5. format. */
/***************************************************************/
%macro drawlab(y, b, t);
rc = gdraw('text', 10, &y-3, put(&b,best5.));
rc = gdraw('text', 95, &y-3, put(&t,best5.));
%mend drawlab;
/***************************************************************/
/* PAIRWISE: creates one page of pairwise comparison plots. */
/* This macro only works for data sets with at least */
/* five continuous numeric variables to plot. */
/* */
/* You must supply values for the macro when you */
/* invoke it as described in the following table: */
/* */
/* ARGUMENT VALUE */
/* -------- ----- */
/* INDS: input data set containing variables to plot */
/* LINE: SAS/GRAPH color for axis lines */
/* SYMBOL: SAS/GRAPH color for symbols */
/* TEXT: SAS/GRAPH color for text */
/* VAR1-VAR5: names of the five variables to plot */
/* CLASS: the class variable to use to determine the */
/* different line colors and line types that */
/* connect the data points */
/* ORDER: order to draw horizontal lines (axes) to */
/* represent variables in the plot, starting */
/* with the top axis (for example, 12345 or */
/* 53412) where different orders allow the */
/* axes to represent different variables. */
/* */
/* REQUIRMENTS: Sort INDS by CLASS. */
/* Have DRAWLAB macro (shown above) available */
/* for labels. */
/***************************************************************/
%macro pairwise(inds, line, symbol, text,
var1, var2, var3, var4, var5,
class, order);
/* The following DATA step produces plots based on the input data */
/* set (represented by the reference &inds) merged with the modified */
/* statistical summary data set (_range_), created in the DATA step */
/* in the MVPLOT macro. */
data _null_;
/* Make sure variables containing the Y axis coordinates and line */
/* type loop index persist across DATA step iterations. */
retain y1 y2 y3 y4 y5 lintype;
/* Merge input data set with modified stat summary data set. */
merge &inds _range_ end=eof;
/* The following loop converts actual plot variable values to DSGI */
/* window coordinates for each variable in the current observation. */
/* */
/* &&var&i resolves to the variable names specified as parameters. */
/* */
/* min&i resolves to names of variables containing lower limit */
/* ranges. */
/* */
/* display&i resolves to names of variables containing factors to */
/* convert the actual values of each plot variable to DSGI coordinate*/
/* values between 0 and 100, plus a minimum value of 10 to maintain */
/* a white space border around the edge of the final plot. */
/* */
/* As a result of this calculation, the minimum value for each */
/* variable produces the DSGI X coordinate value 10, and the maximum */
/* value for each variable produces the DSGI X coordinate 95. */
%do i=1 %to 5;
x&i = (&&var&i - min&i) * display&i + 10;
%end;
/* Everything in the following DO grouop, including the embedded */
/* loops, executes only once at the beginning of the DATA step. */
if _n_=1 then do;
/* The following loop creates five variables, Y1-Y5, each */
/* containing DSGI Y coordinate values of 20, 35, 50, 65, or 80, */
/* but in the order given in the parameter ORDER. */
/* */
/* These Y values were chosen to provide evenly spaced horizontal */
/* axis lines in the output using the DSGI coordinate numbering */
/* system. */
/* */
/* The numeric suffix of each variable corresponds to the macro */
/* variables &VAR1-&VAR5. So, for example, if you specify */
/* ORDER=54321 at invocation, the value of Y5 is 80, and the fifth*/
/* variable passed to the macro will be represented on the */
/* uppermost horizontal axis. */
/* */
/* The loop begins with a hardcoded uppermost DSGI coordinate of */
/* 80, in a display scaled to a coordinate system using values */
/* between 0 and 100. */
pos = 80;
%do i=1 %to 5;
%let s&i = %substr(&order, &i, 1);
%let s = &&s&i;
y&s = pos;
pos = pos - 15;
%end;
/* Initialize DSGI. The GRAPH('CLEAR') function creates a graphics*/
/* catalog entry and prepares it to collect the graphics elements */
/* that you want to display. */
rc = ginit();
rc = graph('clear');
/* Open the window to contain the plot at 100 percent of screen */
/* capacity, and activate the window. */
rc = gset('window', 1, 0, 0, 100, 100);
rc = gset('transno', 1);
/* Set up colors for axis line, text, and plot symbols by */
/* associating color names with the color index numbers. */
rc = gset('colrep', 50, "&LINE");
rc = gset('colrep', 51, "&TEXT");
rc = gset('colrep', 52, "&SYMBOL");
/* Choose font, choose text color, set alignment, and set size; */
/* then write a title for the plot (which includes the names of */
/* all the variables) centered at the top of the page. The text */
/* height and centering position are each in DSGI coordinate */
/* units. */
rc = gset('texfont', 'swissl');
rc = gset('texcolor', 51);
rc = gset('texalign', 'center', 'base');
rc = gset('texheight', 3);
rc = gdraw('text', 50,95,
"Comparing &VAR1,&VAR2,&VAR3,&VAR4,&VAR5");
/* Choose font and line color, then loop to draw the Y axes for */
/* each variable in the order specified at invocation. The minimum*/
/* and maximum values for each axis appear in the font specified; */
/* in the example, they appear in the simplex font. */
rc = gset('texfont', 'simplex');
rc = gset('lincolor', 50);
%do i=1 %to 5;
rc = gdraw('line', ., 10, 95, y&i, y&i);
%end;
/* Set text height, then loop calling the DRAWLAB macro to label */
/* each axis with the min and max values of the variable */
/* associated with each axis. */
%do i=1 %to 5;
%drawlab(y&i, min&i, max&i);
%end;
/* Set text height, choose font, set alignment, then loop to label*/
/* each Y axis with the correct variable name. */
rc = gset('texheight', 3);
rc = gset('texfont', 'swissl');
rc = gset('texalign', 'left', 'base');
%do i=1 %to 5;
rc = gdraw('text', 0, y&i, "&&VAR&I");
%end;
/* Begin the plots with an initial line type. The number refers */
/* to the nth color in the default colors list of the device */
/* driver you are using. */
/* */
/* Later, the line type changes based on a change in the CLASS */
/* variable value. */
/* */
/* For color plots, change the line type instead. */
lintype = 1;
rc = gset('lincolor', 1);
rc = gset('lintype', lintype);
/* Set the point plot symbol color, type, and size. In this */
/* example, the MARTYPE corresponding to the value 67 is an */
/* asterisk. */
/* */
/* See p. 719 of the SAS/GRAPH Software Reference for a table */
/* with all the symbols you can use and the values to specify for*/
/* MARTYPE. */
rc = gset('marcolor', 52);
rc = gset('martype', 67);
rc = gset('marsize', 4);
/* This is the end of all of the tasks performed at the first */
/* DATA step iteration. */
end;
/* Finally, draw lines connecting the points representing the values*/
/* of each variable in the current observation on each of the axes. */
/* */
/* The variables X&S1-X&S5 and Y&S1-Y&S5 resolve to the DSGI X and */
/* Y coordinates for each plotted data point, but in the order you */
/* specify in ORDER at invocation time. */
rc = gdraw('line', ., x&s1, x&s2, x&s3, x&s4, x&s5,
y&s1, y&s2, y&s3, y&s4, y&s5);
/* Draw the plot symbols at each plotted data point on each axis in */
/* the specified order. */
rc = gdraw('mark', ., x&s1, x&s2, x&s3, x&s4, x&s5,
y&s1, y&s2, y&s3, y&s4, y&s5);
/* Check to see if the CLASS variable value changes, and change the */
/* line type (or, alternatively, line color) if it does change. */
if lag(&class) ne &class then do;
lintype + 1;
rc=gset('lintype', lintype);
end;
/* if no more data, close the GRSEG entry, close DSGI, and terminate*/
/* the DATA step. */
if eof then do;
rc=graph('update');
rc=gterm();
end;
run;
%mend pairwise;
/***************************************************************/
/* MVPLOT: Creates a three page chart showing all the */
/* pairwise comparisons of five variables. The */
/* variables are ordered in successive calls of the */
/* PAIRWISE macro in order to get all pairings */
/* in order to get all pairings. */
/* */
/* ARGUMENT VALUE */
/* -------- ----- */
/* INDS: input data set containing variables to plot */
/* LINE: SAS/GRAPH color for axis lines */
/* SYMBOL: SAS/GRAPH color for symbols */
/* TEXT: SAS/GRAPH color for text */
/* VAR1-VAR5: names of the five variables to plot */
/* CLASS: class variable to use to trigger different */
/* style for lines connecting two data points */
/* */
/* REQUIREMENTS: Have DRAWLAB macro available for labels. Have */
/* PAIRWISE macro available for plots */
/***************************************************************/
%macro mvplot(inds, line, symbol, text,
var1, var2, var3, var4, var5, class);
/* Sort the input data set by the class variable to enable changing */
/* plot line colors when the value of the class variable changes. */
proc sort data=&inds; by class; run;
/* The following PROC MEANS step calculates the minimum, maximum, and */
/* range for each plot variable, and the number of observations to */
/* use when merging with the input data set in a later DATA step. The */
/* result of this step is a data set with one observation. */
proc means data=&inds noprint;
var &var1 &var2 &var3 &var4 &var5;
output out= _mvmean_ n=num
range=range1 range2 range3 range4 range5
max=max1 max2 max3 max4 max5
min=min1 min2 min3 min4 min5;
run;
/* The following DATA step */
/* */
/* o creates a factor for each variable plotted based on the range */
/* of values it contains and used to convert actual data values to */
/* DSGI coordinates (values between 0 and 100) in a later DATA */
/* step; factores are stored in DISPLAY1-DISPLAY5. */
/* */
/* o transforms the factors to ensure no more than 85 percent of the */
/* horizontal space on the plot is used to leave a white space */
/* border around the edges for aesthetic reasons. */
/* */
/* o takes the input statistics data set (containing only one */
/* observation) and copies its single observation repeated to */
/* create a data set having the same number of observations as the */
/* data set containing the variables to plot; this step is */
/* necessary so that a subsequent DATA step can merge the */
/* statistics data set and plot data set. */
data _range_;
set _mvmean_;
%do i=1 %to 5;
display&i = 85 / range&i;
%end;
keep display1 display2 display3 display4 display5
max1 max2 max3 max4 max5
min1 min2 min3 min4 min5 num;
do i=1 to num; output; end;
run;
%pairwise(&inds, &line, &symbol, &text, &var1, &var2, &var3,
&var4, &var5, &class, 12345);
%pairwise(&inds, &line, &symbol, &text, &var1, &var2, &var3,
&var4, &var5, &class, 13524);
%pairwise(&inds, &line, &symbol, &text, &var1, &var2, &var3,
&var4, &var5, &class, 25143);
%mend mvplot;
/* get some data and invoke the macro */
data cars;
length make $ 10 model $ 11;
input make $ model $ class weight cuin gears price mpg;
cards;
Chevrolet Chevette 1 2200 98 2.89 5959 36
Honda Civic 1 2035 91 3.03 7798 30.5
Toyota Corolla 1 2270 97 2.70 7348 35.5
Ford Mustang 2 2860 140 3.08 7189 23
Honda Prelude 2 2345 112 3.08 10980 31.5
Pontiac Fiero 2 2530 151 2.48 8949 29
Cadillac Cimarron 3 2620 121 2.96 13128 28
Nissan Stanza 3 2440 121 2.60 10069 34
Volkswagen Quantum 3 2640 136 3.14 13595 21.5
Buick Century 4 2775 151 2.39 10228 27
Ford Thunderbird 4 3190 232 2.73 11020 22.5
Pontiac 6000 4 2785 151 2.84 9729 22
Buick Electra 5 3300 231 1.99 15588 23.5
Lincoln TownCar 5 4060 302 2.06 20764 22
Pontiac Parisienne 5 3630 262 2.56 11169 21.5
Dodge Caravan 6 3005 135 2.56 9659 22
Ford Aerostar 6 3475 140 3.17 9418 18
Volkswagen Vanagon 6 3370 129 4.11 12540 16
;
run;
%mvplot(cars, black, black, black,
weight, cuin, gears, price, mpg, class);
*;