楼主: cynthialam
4277 24

[原创博文] 【Help】SAS综合查询,定义新指标 [推广有奖]

11
cynthialam 发表于 2012-1-11 09:17:47
soporaeternus 发表于 2011-12-22 09:36
类似的搜索都可以用hash来实现,就是做之前需要预判hash的大小,以免内存不够
恩,谢了~学习了Hash~

研究了一下,这段代码的结果会随着数据排序的不同有不同的结果,因为在Grp+1这条上,没有判断是否属于现有群组了...

不知能不能再指导一下,如何判断咩?

12
soporaeternus 发表于 2012-1-11 10:57:07
cynthialam 发表于 2012-1-11 09:17
恩,谢了~学习了Hash~

研究了一下,这段代码的结果会随着数据排序的不同有不同的结果,因为在Grp+1这条 ...
不是很理解,grp只是一个自增组号~
Let them be hard, but never unjust

13
maidenhan 发表于 2012-1-11 16:18:28
I had met such problems in my business, and I would like to share my way to handlt it.

data test01;
input a b;
cards;
1 9
4 3
3 2
5 6
7 8
8 5
7 6
9 3
;run;

data test02(drop = t);
        set test01;
        if b > a then output;
        t = a;
        a = b;
        b = t;
        if b > a then output;
run;
proc sort data = test02;
        by a b;
run;
data test03;
        set test01(keep = a rename=(a = ab))
                test01(keep = b rename=(b = ab));
run;
proc sort data = test03 nodupkey;
        by ab;
run;

%macro test_macro();
%let grp = 0;
%do flag1 = 1 %to 0 %by -1;
        %let grp = %eval(&grp.+1);
        %do flag2 = 1 %to 0 %by -1;
                %let ds_flag = %sysfunc(open(temp01,is));
                %if &ds_flag. = 0 %then %do;   
                        data _null_;
                                if _n_ = 1 then do;
                                        dcl hash h();
                                        h.definekey("ab");
                                        h.definedata("ab");
                                        h.definedone();
                                end;
                                set test02 end=eof;
                                if _n_ = 1 then do;
                                        ab = a; h.add();
                                        ab = b; h.add();
                                end;else do;
                                        if h.find(key:a) = 0 and h.find(key:b) then do;
                                                ab = b; h.add();
                                        end;else if h.find(key:a) and h.find(key:b) = 0 then do;
                                                ab = a; h.add();
                                        end;
                                end;
                                if eof then h.output(dataset:"temp01");
                        run;
            %end;   
            %else %do;   
                %let ds_close = %sysfunc(close(&ds_flag.));
                        data _null_;
                                if 0 then set temp01;
                                if _n_ = 1 then do;
                                        dcl hash h(dataset:"temp01");
                                        h.definekey("ab");
                                        h.definedone();
                                end;
                                set test02 end=eof;
                                if h.find(key:a) = 0 and h.find(key:b) then do;
                                        ab = b; h.add();
                                end;else if h.find(key:a) and h.find(key:b) = 0 then do;
                                        ab = a; h.add();
                                end;
                                if eof then h.output(dataset:"temp02");
                        run;
                        proc sql noprint;
                                select count(*) into:t1 from temp01;
                                select count(*) into:t2 from temp02;
                        quit;
                        data temp01; set temp02; run;
                        %if &t1. = &t2. %then %let flag2 = -10;
                        %else %let flag2 = 1;
                %end;
        %end;
        data temp01; set temp01; grp = &grp.; run;
        proc append base = temp03 data = temp01; run;
        data test02;
                if 0 then set temp03;
                if _n_ = 1 then do;
                        dcl hash h(dataset:"temp03");
                        h.definekey("ab");
                        h.definedone();
                end;
                set test02;
                if h.find(key:a) and h.find(key:b);
        run;
        proc sql noprint;
                select count(*) into:tp3 from temp03;
                select count(*) into:tt3 from test03;
                drop table temp01;
                drop table temp02;
        quit;
        %if &tp3. = &tt3. %then %let flag1 = -10;
        %else %let flag1 = 1;
%end;
%mend;
%test_macro();

14
zhangzachary 发表于 2012-1-11 16:53:13
soporaeternus 发表于 2012-1-11 10:57
不是很理解,grp只是一个自增组号~
你把13楼test02这一部分加到hash前面应该就可以了~
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

15
zhangzachary 发表于 2012-1-11 16:58:26
soporaeternus 发表于 2012-1-11 10:57
不是很理解,grp只是一个自增组号~
不对,加了也没用。。。碰到
1 8
2 8
3 8
4 8
这样的就不行了。。。
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

16
zhangzachary 发表于 2012-1-12 11:52:06
提供一个不用hash的code,你试试看有没有bug~
  1. data a; /* 这里a的数据尽量多试几个新的结构的,避免投机~ */
  2. input A B;
  3. cards;
  4. 1 9
  5. 4 3
  6. 3 2
  7. 5 6
  8. 7 8
  9. 8 5
  10. 7 6
  11. 9 3
  12. ;
  13. run;

  14. data aa;
  15. set a a(rename=(A=B B=A));
  16. run;

  17. proc sort data=aa;
  18. by a b;
  19. run;

  20. data aa;
  21. set aa;
  22. G=min(a,b);
  23. run;


  24. %macro ff();
  25. %do i=0 %to 9 ; /* 如果只是0-9应该够用了,本来想写条件循环,不过水平有限,总是出错~ */

  26. proc sort data=aa;
  27.   by b G;
  28. run;

  29. data aa;
  30.   set aa;
  31.   by b;
  32.   retain change 0;
  33.   if first.b then change=G;
  34.   G=change;
  35.   drop change ;
  36. run;

  37. proc sort data=aa;
  38.   by a G;
  39. run;

  40. data aa;
  41.   set aa ;
  42.   by a;
  43.   retain change  0;
  44.   if first.a then change=G;
  45.   G=change;
  46.   drop change;
  47. run;

  48. %end;

  49. %mend ff;

  50. %ff()
复制代码
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

17
zhangzachary 发表于 2012-1-12 11:53:24
之后rank一下G就可以了~
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

18
zhangzachary 发表于 2012-1-12 11:54:34
soporaeternus 发表于 2011-12-22 09:36
类似的搜索都可以用hash来实现,就是做之前需要预判hash的大小,以免内存不够
马尔科夫兄,帮我看下16楼的程序啊,谢谢~~
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

19
zhangzachary 发表于 2012-1-12 12:02:15
  1. proc sort data=aa;
  2.   by G;
  3. run;

  4. data aa;
  5.   set aa;
  6.   by G;
  7.   retain group 0;
  8.   if first.G then group+1;
  9.   keep a group;
  10. run;

  11. proc sort data=aa;
  12.   by a;
  13. run;

  14. data aa;
  15.   set aa;
  16.   by a;
  17.   if first.a;
  18. run;
复制代码
最后再补充点后续处理的过程,我这里使用比较麻烦,所以这个就没有运行验证,不过只要前面的对了,这段程序并不重要~
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

20
cynthialam 发表于 2012-1-12 14:09:28
maidenhan 发表于 2012-1-11 16:18
I had met such problems in my business, and I would like to share my way to handlt it.

data test0 ...
macro?!
那好吧....

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

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