houliping
"A Handbook of Statistical Analyses using SAS"这本书后的附录里提供了一个可以做散点图矩阵的宏。你可以试一试。
%macro scattmat(data,vars);
/* This macro is based on one supplied with the SAS system,
but has been adapted and simplified. It uses PROC IML and
therefore requires that SAS/IML be licensed.
The macro has two arguments: the first is the name of the
SAS data set that contains the data to be plotted; the second
is a list of numeric variables to be plotted. Both arguments
are required.
The macro takes a pairwise approach to missing values.
*/
/* expand variable list and separate with commas */
data _null_;
set &data (keep=&vars);
length varlist $500. name $32.;
array xxx {*} _numeric_;
do i=1 to dim(xxx);
call vname(xxx{i},name);
varlist=compress(varlist||name);
if i<dim(xxx) then varlist=compress(varlist||',');
end;
call symput('varlist',varlist);
stop;
run;
proc iml;
/*-- Load graphics --*/
call gstart;
/*-- Module : individual scatter plot --*/
start gscatter(t1, t2);
/* pairwise elimination of missing values */
t3=t1;
t4=t2;
t5=t1+t2;
dim=nrow(t1);
j=0;
do i=1 to dim;
if t5=. then ;
else do;
j=j+1;
t3[j]=t1;
t4[j]=t2;
end;
end;
t1=t3[1:j];
t2=t4[1:j];
/* ---------------- */
window=(min(t1)||min(t2))//
(max(t1)||max(t2));
call gwindow(window);
call gpoint(t1,t2);
finish gscatter;
/*-- Module : do scatter plot matrix --*/
start gscatmat(data, vname);
call gopen('scatter');
nv=ncol(vname);
if (nv=1) then nv=nrow(vname);
cellwid=int(90/nv);
dist=0.1*cellwid;
width=cellwid-2*dist;
xstart=int((90 -cellwid * nv)/2) + 5;
xgrid=((0:nv-1)#cellwid + xstart)`;
/*-- Delineate cells --*/
cell1=xgrid;
cell1=cell1||(cell1[nv]//cell1[nv-(0:nv-2)]);
cell2=j(nv, 1, xstart);
cell2=cell1[,1]||cell2;
call gdrawl(cell1, cell2);
call gdrawl(cell1[,{2 1}], cell2[,{2 1}]);
xstart = xstart + dist; ystart = xgrid[nv] + dist;
/*-- Label variables ---*/
call gset("height", 3);
call gset("font","swiss");
call gstrlen(len, vname);
where=xgrid[1:nv] + (cellwid-len)/2;
call gscript(where, 0, vname) ;
len=len[nv-(0:nv-1)];
where=xgrid[1:nv] + (cellwid-len)/2;
call gscript(0,where, vname[nv - (0:nv-1)]);
/*-- First viewport --*/
vp=(xstart || ystart)//((xstart || ystart) + width) ;
/* Since the characters are scaled to the viewport */
/* (which is inversely porportional to the */
/* number of variables), */
/* enlarge it proportional to the number of variables */
ht=2*nv;
call gset("height", ht);
do i=1 to nv;
do j=1 to i;
call gportstk(vp);
if (i=j) then ;
else run gscatter(data[,j], data[,i]);
/*-- onto the next viewport --*/
vp[,1] = vp[,1] + cellwid;
call gportpop;
end;
vp=(xstart // xstart + width) || (vp[,2] - cellwid);
end;
call gshow;
finish gscatmat;
/*-- Placement of text is based on the character height. */
/* The IML modules defined here assume percent as the unit of */
/* character height for device independent control. */
goptions gunit=pct;
use &data;
vname={&varlist};
read all var vname into xyz;
run gscatmat(xyz, vname);
quit;
goptions gunit=cell; /*-- reset back to default --*/
%mend;