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