SAS中文论坛

标题: 如何将一组观测值按大小等分成n组? [打印本页]

作者: shiyiming    时间: 2010-3-17 13:04
标题: 如何将一组观测值按大小等分成n组?
例如有一组beta, 777个,将其从小到大排列。如下:
Com  beta
A      0.8
B      0.9
C      1.1

......

怎样将其分成20组,分别导出到20个文件?
作者: shiyiming    时间: 2010-3-17 13:50
标题: Re: 如何将一组观测值按大小等分成n组?
[code:2qk681in]data a;
   do var=1 to 777;
      output;
   end;
run;

%macro temp(in_ds,out_ds,group);
   options nomprint;
   %let dsid=%sysfunc(open(&in_ds,i));
   %let nobs=%sysfunc(attrn(&dsid,nlobs));
   %let rc=%sysfunc(close(&dsid));
   %let interval=%sysevalf(&nobs/&group,ceil);
   %do i=0 %to %eval(&group-1);
      data &out_ds._%eval(&i+1);
         set &in_ds (firstobs=%eval(&i*&interval+1) obs=%eval((&i+1)*&interval));
      run;
   %end;
%mend;

%temp(a,b,20)[/code:2qk681in]
<!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2010-3-17 16:13
标题: Re: 如何将一组观测值按大小等分成n组?
thxs, 不过我是个初学者,还不懂macro。先琢磨一下
作者: shiyiming    时间: 2010-3-17 17:40
标题: Re: 如何将一组观测值按大小等分成n组?
可以用,太帅了!

不过我需要更改一下每组的数目,一共是20组,中间18组,每组数目是int(N/20)。剩下的平均分配到第一组和最后一组,如果是N为奇数,那么第一组比最后一组多1个。这样的话,code 需要如何修改呢?
作者: shiyiming    时间: 2010-3-17 20:31
标题: Re: 如何将一组观测值按大小等分成n组?
[code:2oqg9431]%macro temp(in_ds,out_ds,group);
   options nomprint nosymbolgen;
   %let dsid=%sysfunc(open(&amp;in_ds,i));
   %let nobs=%sysfunc(attrn(&amp;dsid,nlobs));
   %let rc=%sysfunc(close(&amp;dsid));
   %let interval=%sysevalf(&amp;nobs/&amp;group,floor);
   %let oddment=%sysevalf(%sysfunc(mod(&amp;nobs,&amp;group))/2,ceil);
   data &amp;in_ds;
      set &amp;in_ds;
      retain _group 1;
      if _n_&gt;&amp;oddment+1 then _group=ifn(mod(_n_-&amp;oddment,&amp;interval)=1,_group+1,_group);
      _group=ifn(_group&gt;&amp;group,_group-1,_group);
   run;
   %do i=1 %to &amp;group;
      data &amp;out_ds&#46;_&amp;i(drop=_group);
         set &amp;in_ds (where=(_group=&amp;i));
      run;
   %end;
%mend;[/code:2oqg9431]
作者: shiyiming    时间: 2010-3-18 01:31
标题: Re: 如何将一组观测值按大小等分成n组?
how about this one?  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->

[code:1p9aakfh]
data x;
     do i=1 to 777;
            output;
         end;
run;


%macro hashinit;
     h = _new_ hash(ordered&#58;'a');
         h&#46;defineKey('id');
         h&#46;defineData('id', 'i');
         h&#46;defineDone();
%mend;

data _null_;
     declare hash h();
     %hashinit;

         array _p{1&#58;20} p1-p20;
         retain p1-p20;
         retain j j1 j2 id 0;
         id=1; _n=1;
         do until (eof);
            set x end=eof  nobs=ntotal;
        if _n=1 then do;
                   j=round(ntotal/20); j1=round((ntotal-j*18)/2); j2=ntotal-j*18-j1;
                   _p&#91;1&#93;=j1;
                   do _i=2 to 19;                  
            _p&#91;_i&#93;=j1+(_i-1)*j;
                   end;
                   _p&#91;20&#93;=ntotal;
                   put j= j1= j2= //;
            put _p&#91;*&#93;=;
                end;
                rc=h&#46;add();
                id+1;
                _x=whichN(_n, of _p&#91;*&#93;);
                if _x&gt;0 then do;
                   put _n=  _x=;
                   rc=h&#46;output(dataset&#58;compress('j'||_x));
                   rc=h&#46;delete();
                   id=1;
                   %hashinit;
                end;
                _n+1;
        end;
run;

[/code:1p9aakfh]
作者: shiyiming    时间: 2010-3-18 09:03
标题: Re: 如何将一组观测值按大小等分成n组?
先add到hash object,到达分组末尾后再output到数据集?看理解的对不
[code:3peqy4jx]data _null_;
        declare hash h(); /* 声明hash object */
        %hashinit;  /* 实例化hash object */

        array _p{1&#58;20} p1-p20; /* 数组p,存储每组最后一个观测的序号 */
        retain p1-p20;
        retain j j1 j2 id 0;
        id=1;  /* hash object的key变量 */
        _n=1;  /* obs的序号(_n_) */

        do until(eof);
                set x end=eof  nobs=ntotal;
                if _n=1 then  /* 读取第1条记录时执行 */
                        do;
                                j=round(ntotal/20);  /* 2-19组的观测个数 */
                                j1=round((ntotal-j*18)/2);  /* 第1组的观测个数 */
                                j2=ntotal-j*18-j1;         /* 第20组的观测个数 */
                                _p&#91;1&#93;=j1; /* 为数组p的元素赋值 */
                                do _i=2 to 19;         
                                        _p&#91;_i&#93;=j1+(_i-1)*j;
                                end;
                                _p&#91;20&#93;=ntotal;
                                put j= j1= j2= //; /* 打印j,j1,j2的值 */
                    put _p&#91;*&#93;=;         /* 打印数组_p各元素的值 */
                        end;

                rc=h&#46;add();        /* add变量值到hash object */
                id+1; /* key变量值+1 */
                _x=whichN(_n, of _p&#91;*&#93;); /* whichn()判断是否到达每组的末尾 */

                if _x&gt;0 then  /* 到达分组末尾时执行 */
                        do;
                                put _n=  _x=; /* 打印_n,_x的值 */
                                rc=h&#46;output(dataset&#58;compress('j'||_x));        /* 输出hash object到数据集 */
                                rc=h&#46;delete(); /* delete hash object */
                                id=1;  /* 重置id初值 */
                                %hashinit; /* 重新实例化hash object */
                        end;

                _n+1; /* obs序号+1 */
        end;
run;[/code:3peqy4jx]
作者: shiyiming    时间: 2010-3-18 23:27
标题: Re: 如何将一组观测值按大小等分成n组?
to hopewell
en, correct
作者: shiyiming    时间: 2010-3-19 09:51
标题: Re: 如何将一组观测值按大小等分成n组?
为啥大家没有人提议proc surveyselect呢?现成的过程步,多好用啊。
作者: shiyiming    时间: 2010-3-19 10:28
标题: Re: 如何将一组观测值按大小等分成n组?
很简单,因为你还是没法给每个小文件赋予单独的名字
这么说来,不比那个macro的方法简单




欢迎光临 SAS中文论坛 (http://www.mysas.net/forum/) Powered by Discuz! X3.2