楼主: yiqiangz
2163 12

请问两个SAS编程的问题(有一个来自京剧的quantile测序)。 [推广有奖]

11
yiqiangz 发表于 2014-4-25 11:28:01 |只看作者 |坛友微信交流群
好吧,我把我的代码贴上来。我借用了你的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);

使用道具

12
jingju11 发表于 2014-4-25 12:30:28 |只看作者 |坛友微信交流群
yiqiangz 发表于 2014-4-25 11:28
好吧,我把我的代码贴上来。我借用了你的quantile的代码(数组+proc format的方法比我的快),运行良好。我 ...
程序真是很难理解。如果分割成sub-macro 的形式,要好些。&rn.&I_ 是按照行来读。...[I] 要算的是i-row的平均数。改成其他的index当然可以。只要是外循环跟着改动即可。京剧

使用道具

13
yiqiangz 发表于 2014-4-25 17:52:04 |只看作者 |坛友微信交流群
呵呵,早点拨一下就好了。
arr_r里带的[I] 要算的是i-row的平均数,是的,刚才才意识到do i =1 to &n_obs.是实变量循环,不是宏变量循环。用[I]是必须的。

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-1 12:21