楼主: harlon1976
6007 34

[原创博文] 请教这个程序应该如何编写 [推广有奖]

21
harlon1976 发表于 2010-3-13 06:11:04
比如说使用means过程对该数据集进行分析。我所要问的问题实际上如何将随机数与数据集结合形成如dest1、dest2。或者说如何从dest1-dest10中随机选取这些数据集。兄弟请帮忙。

22
jingju11 发表于 2010-3-13 08:37:23
harlon1976 发表于 2010-3-13 06:11
比如说使用means过程对该数据集进行分析。我所要问的问题实际上如何将随机数与数据集结合形成如dest1、dest2。或者说如何从dest1-dest10中随机选取这些数据集。兄弟请帮忙。

%macro MeansMcr(D);
   proc means data = &D;
   run;
%mend MeansMcr;

data _null_;
   do i = 1 to 10;*assumed 10;
      r = ceil(ranuni(1)*10);

      D = cats('d', put(r, best.));
      call execute('%MeansMcr(' ||D||')');
   end;

run;

*it is possible that you will run 10 times on data d1, even very unlikely;
*please read Deng's code: it is so good;
JingJu

23
harlon1976 发表于 2010-3-13 09:35:04
非常感谢你的程序,我想问问,那个 ||D||的含义是什么,谢谢。
另外请你到这个帖子的第一楼,点击我来解答,领取100论坛币。再次感谢兄弟的帮助。

24
jingju11 发表于 2010-3-13 10:36:58
jingju11 发表于 2010-3-13 08:37
harlon1976 发表于 2010-3-13 06:11
比如说使用means过程对该数据集进行分析。我所要问的问题实际上如何将随机数与数据集结合形成如dest1、dest2。或者说如何从dest1-dest10中随机选取这些数据集。兄弟请帮忙。

%macro MeansMcr(D);
   proc means data = &D;
   run;
%mend MeansMcr;

data _null_;
   do i = 1 to 10;*assumed 10;
      r = ceil(ranuni(1)*10);

      D = cats('d', put(r, best.));
      call execute('%MeansMcr(' ||D||')');
   end;

run;

*it is possible that you will run 10 times on data d1, even very unlikely;
*please read Deng's code: it is so good;
JingJu

Change to:
D = cats('dest', put(r, best.));

r = ceil(ranuni(1)*10);*the 10 is really depending on how many dsets you have. for example, if you have datasets (in WORK library) from dest1-dest50, so you should times 50, and so on;
Sure I will get my money! Thanks.

25
harlon1976 发表于 2010-3-13 12:32:07
你提到的两点我自己也发现了,你的说明也印证了我的猜想,我的那个问题那个: ||D||的含义是什么?
请给予解答,谢谢。

26
harlon1976 发表于 2010-3-13 12:48:48
最后在问一个问题:如果不考虑变量x,只需将A、B的10种组合生成即可,或者说dset1-dset10中不需要变量x,程序如何修改,我使用12楼的程序,对于16=9+7的组合竟然系统提示磁盘已满,请兄弟再指点迷津。

27
jingju11 发表于 2010-3-13 13:51:42
harlon1976 发表于 2010-3-13 12:48
最后在问一个问题:如果不考虑变量x,只需将A、B的10种组合生成即可,或者说dset1-dset10中不需要变量x,程序如何修改,我使用12楼的程序,对于16=9+7的组合竟然系统提示磁盘已满,请兄弟再指点迷津。
那只是call execute 的语法,请查阅参考。

12楼的程序很好,可以做超过两个水平的组合。方法是先做任意组合,此为2**16 = 65536,然后剔除不合乎要求的,剩下c(16, 9) = 11440. 设想一下差不多是65536×16(位数字)= 16,777,216,上千万次的调用,因此磁盘已满不为怪。如果使用proc plan直接生成11,440 个不同组合,每个组合含有9个变量,或者是7个变量(如果你考虑B的话),c(16,9) = c(16,7).或许会有所改善。此时所生成的数据,有9个A(或者7个B)的话,9个变量代表每个A在16个空格中所占有的位置。因此你只要把没有占有的位置用B来填充即可。
如果我理解正确的话,16=9+7将产生11440个数据表格,每个表格含有16个观察值。

28
bobguy 发表于 2010-3-14 01:35:49
harlon1976 发表于 2010-3-11 15:39
假设数据集中有变量两个,分别为数值型的x和字符型的class。假设有如下5个观测:
x     class
1      A
5      B
4      A
2      B
8      A
在这个数据集中,变量class有两个取值,分别为A、B,如果现在考察对变量class进行重新排序,根据概率论知识:这里有5条观测,分成两类,一类(A类)有3个,第二类(B类)有2个,则可以重新组合的结果为10种,例如下面的结果就是其中的两种:
x         class                x           class
1            A                   5              B
4            A                   2              B
8            A                   8              A
5            B                  1               A
2            B                  4               A
现在的问题是:如何根据原始的数据集,编写SAS程序生成所有的10种结果。
如果现在不只是A、B两类,比如3类,类似的程序又如何编写呢?请高手给予解决。
The following solution is based SAS provided conbination macro. It can be found at,
Reference: http://support.sas.com/techsup/technote/ts498.html  (thanks to jackbt123)

I add the count variable to determine which number of the combination is needed.

The macro will calculate the obsevation index for a particular combination. The index is the number of observation position on the data set(it is variable i in the following pgm .

After one has the index, then one can retrieve that data with that index + the completement of that index.

Hope this helps.


  %macro combo(r)/parmbuff;

      %let i=2;
      %let things=;
      %do %while (%Qscan(&syspbuff,&i,%STR(,%))) ne );
        %let p&i="%Qscan(&syspbuff,&i,%STR(,%)))";
        %if &i=2 %then %let things=&&p&i;
        %else %let things=&things,&&p&i;
        %let i=%eval(&i+1);
      %end;
      %let n=%eval(&i-2);
       data combo;
            keep v1-v&r count;
            array word $8  w1-w&n (&things);
            array rr (*) r1-r&r;
            array v $8  v1-v&r;
           %do i=1 %to &r;                    /* create the DO LOOPs */
             %if &i=1 %then %do;
               do r&i=1 to &n-(&r-&i);
               %end;
             %else %do;
               do r&i=r%eval(&i-1)+1 to &n-(&r-&i);
               %end;
             %end;
             count+1;
               do k=1 to &r;              /* select subscripted items */           
               v(k)=word (rr(k));               /* for a SAS data set */
               *put v(k)      '  ' @;                       /* for log */
               end;
               *put;                                  /* writes to log */
               output;                    /* writes to a SAS data set */
           %do i=1 %to &r;
             end;                     /* create ENDs for the DO LOOPs */
             %end;
            put;
            run;
         proc print uniform data=combo;
            title "combinations of &n items taken &r at a time ";
            run;
       %mend combo;
option mprint;
data t1 t2;
   do i=1 to 15;
      a=byte(i+64);
      output;
   end;
run;

%let n=10;

%let dsnnum=8;

proc sql noprint;
select i into : vlist separated by ','
from t1;
%put &vlist;
quit;
   
%combo(&n,&vlist)

data _null_;
  length index $2000;
  set combo(where=(count= &dsnnum));
  array v(*) v1-v&n;
  index=catx(',',  of v(*));
  call symputx('index', index);
run;

data t2;
   set t1;
   if i in (&index) then class='A';
   else                       class='B';
run;

proc print; run;

29
jackbt123 发表于 2010-3-14 12:44:42
Hi bobguy,
should we consider the duplicate cases?
for instance,
x class
1 A
1 B
Thanks

30
gzndxf 发表于 2010-3-14 14:52:37
向九楼的学习。

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-30 05:28