*
;
/*----------------------------------------------------*
| Scale >> each << variable to range from Lo to Hi |
*----------------------------------------------------*/
%macro SCALE (
data=_LAST_, /* input data set */
var=_NUMERIC_, /* variables to be scaled */
copy=, /* variables to be copied unchanged */
id=, /* id variable (required!) */
out=_DATA_ , /* output data set */
outstat=, /* output min/max dataset */
minmax=, /* optional dataset of min/vax values */
lo=0, /* low value of new range */
hi=1); /* high value */
%local rn;
%let rn=;
proc iml;
reset;
use &data;
%if &id ^= %str() %then %let rn=rowname=&id;
read all var {&var} into x[ &rn colname=vars ];
n = nrow( x);
k = ncol( x);
%if &minmax ^= %str() %then %do;
use &minmax;
read all var{min} into min;
read all var{max} into max;
min = j(n,1) * min`;
max = j(n,1) * max`;
%end;
%else %do;
min = j( n , 1 ) * x[>< ,];
max = j( n , 1 ) * x[<> ,];
%end;
minmax = min[1,]` || max[1,]`;
print "Min/max for data set &data";
print minmax[rowname=vars colname={min max}];
X = &LO + ( &HI - &LO ) * ( X - MIN ) / ( MAX - MIN );
create &out from x[ &rn colname=vars ];
%if &id = %str() %then
%str(append from x;);
%else
%str(append from x[ &rn ];);
%if &outstat ^= %str() %then
%do;
create &outstat from minmax[ rowname=vars colname={min max}];
append from minmax[rowname=vars colname={min max}];
%end;
quit;
%if %length(©) >0 %then %do;
data &out;
merge &out &data(keep=©);
%end;
%mend SCALE;
*Example;
data one;
input x y id $;
cards;
1 2 asc
2 4 bvd
3 6 vjk
4 8 asc
;
run;
%scale(data=one, var=x y, out=two,
lo=0, hi=1);
proc print data=two; run;
*;