好吧,我把我的代码贴上来。我借用了你的quantile的代码(数组+proc format的方法比我的快),运行良好。我的问题是:你的代码中,%let arr_r =&arr_r pre_&i._[i],这里面[i]的作用我不懂,想把这句话搞明白。
%macro Normalize(method,data,out); /*log2 Zscore divSum divQ3 Quantile 5种可选*/
proc contents data=&data noprint out=summary;run;
proc sql noprint;
select count(distinct name) into:nid from summary where name^="SEQ_ID";
select name into :id1-:id%left(&nid) from summary where name^="SEQ_ID";
quit;
%let maxn=%left(&nid);
%if %sysfunc(prxmatch(/log2/i,&method))>0 %then %do;
data &out;set &data;run;
%do i=1 %to &nid;
data &out;
set &out;
&&id&i=log2(&&id&i+0.01); /*log2 transformation*/
run;
%end;
%end;
%else %if %sysfunc(prxmatch(/Zscore/i,&method))>0 %then %do;
proc STDIZE data=&data method=std out=&out; var &id1--&&id&maxn.; run; /*Z-score transformation*/
%end;
%else %if %sysfunc(prxmatch(/divSum/i,&method))>0 %then %do;
data &out;set &data;run;
%do i=1 %to &nid;
proc sql noprint;
select sum (&&id&i) into: sum from &data;
quit;
data &out;
set &out;
if &&id&i^=. then &&id&i=10**6*&&id&i./&sum.; /*Divived by Sum normalization*/
run;
%end;
%end;
%else %if %sysfunc(prxmatch(/divQ3/i,&method))>0 %then %do;
data &out;set &data;run;
%do i=1 %to &nid;
proc means data=raw q3 noprint;
var &&id&i;
output out=stat q3=q3;
run;
data _null_;
set stat;
call symput('q3',q3);
run;
data &out;
set &out;
if &&id&i^=. then &&id&i=&&id&i./&q3.; /*Divided by Q3 normalization*/
run;
%end;
%end;
%else %if %sysfunc(prxmatch(/Quantile/i,&method))>0 %then %do;
%let var_r=; %let arr_r=; %let rn=pre_;
%do i =1 %to &nid;
%let var_r =&var_r &rn.r%sysfunc(putn(&i, z3.));
%let arr_r =&arr_r &rn.&i._[i];
%end;
data _null_;
call symputx('n_obs',nobs);
if 0 then set &data nobs =nobs;
stop;
run;
proc rank data=&data out=&rn.d1 ties=LOW;
var &id1--&&id&maxn.;
ranks &var_r.;
run;
data &rn.d2;
set &rn.d1 end =Eof;
%do i =1 %to &nid;
array &rn.&i._[&n_obs.] _temporary_;
&rn.&i._[_n_] =&&id&i.;
%end;
if Eof then do;
retain fmtname 'NormScr' type 'I';
%do i =1 %to &nid;
call sortn(of &rn.&i._[*]);
%end;
do i =1 to &n_obs.;
label =mean(of &arr_r);
start =i; end =start;
output;
end;
end;
run;
proc format cntlin=work.&rn.d2; run;
data &out;
set &rn.d1;
%do i =1 %to &nid;
&&id&i. =input(%scan(&var_r, &i), NormScr.);
%end;
drop &var_r;
run;
proc datasets nolist; delete &rn.d:; run; quit;
%end;
%else %do;
data &out;set &data;run;
%end;
proc transpose data=raw out=data;
by seq_id;
var &id1--&&id&maxn.;
run;
%mend;
下面是我的quantile的宏,能用,但是速度慢。
%macro quantileN(data,out);
data nor;
set _null_;
run;
proc rank data=&data out=&out ties=LOW;
var &id1--%unquote(%quote(&)id%left(&nid));
ranks id1-id%left(&nid);
run;
%do i=1 %to &nid;
data temp;
set &out;
keep &&id&i;
proc sort;
by &&id&i;
run;
data nor;
merge nor temp;
run;
%end;
data nor;
set nor;
mean=mean(of &id1--%unquote(%quote(&)id%left(&nid)));
call symput('mydummy'||trim(left(_N_)),mean);
run;
%do i=1 %to &nid;
data &out;
set &out;
&&id&i=symget('mydummy'||put(id&i,best.-l));
drop id&i;
run;
%end;
proc datasets nolist; delete nor temp; run; quit;
%mend;
%quantileN(raw,out);