楼主: denver
3713 22

也问“将不同观测按要求重新组合” [推广有奖]

11
zhangzachary 发表于 2013-1-21 11:49:35
  1. data test;
  2. input
  3. n        v1        v3        v5        v8;
  4. datalines;
  5. 1        1        0        1        42345
  6. 2        0        3        1        42310
  7. 3        1        0        1        42490
  8. 4        0        3        1        42450
  9. 5        0        0        1        42475
  10. 6        1        3        1        42535
  11. 7        1        0        1        42630
  12. 8        0        0        1        42770
  13. 9        1        3        1        42875
  14. 10        0        3        1        42725
  15. 11        0        0        1        42810
  16. 12        1        3        1        42880
  17. 13        0        0        1        42790
  18. 14        1        0        1        42715
  19. 15        0        3        1        42740
  20. 16        0        0        1        42760
  21. 17        1        3        2        42825
  22. ;
  23. run;

  24. data test2a test2b;
  25.   set test;
  26.   if (v1=1 and v3=0) or (v1=0 and v3=3) then output test2a;
  27.   if (v1=0 and v3=0) or (v1=1 and v3=3) then output test2b;
  28. run;

  29. data test3a;
  30.   set test2a;
  31.   retain grp;
  32.   lagv3=lag(v3);
  33.   if v3=0 and v3 ne lagv3 then grp=n;
  34. run;

  35. data test3b;
  36.   set test2b;
  37.   retain grp;
  38.   lagv3=lag(v3);
  39.   if v3=0 and v3 ne lagv3 then grp=n;
  40. run;

  41. data test4;
  42.   set test3a test3b;
  43.   by grp;
  44.   retain d;
  45.   if first.grp then d+1;
  46.   drop lagv3 grp;
  47. run;
复制代码
这个可以实现上述例子的情况。但是对于这么一种情况:(v1,v3) = (0,0) (0,0) (1,3) (1,3) 那么我就不知道后面2次平仓分别对应的是哪个开仓。上述程序可以实现(v1,v3) = (0,0) (0,0) (1,3) 即视为最后一次平了前面连续的所有开仓。
已有 1 人评分经验 学术水平 热心指数 信用等级 收起 理由
denver + 100 + 5 + 5 + 5 楼主威武!

总评分: 经验 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

12
zhangzachary 发表于 2013-1-21 12:09:20
我发现用lag多余了。。。不过就先这样吧,免得编辑了又没东西了。。。
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

13
maidenhan 发表于 2013-1-21 14:32:41
纯粹依照楼主例子做的,没有考虑任何其他的可能情况。
楼主先试试,有问题,咱们再改改。
  1. data t1;
  2.         format n v1 v3 v5 8. v8 $10.;
  3.         input n v1 v3 v5 v8 $;
  4. cards;
  5. 1 1 0 1 42345
  6. 2 0 3 1 42310
  7. 3 1 0 1 42490
  8. 4 0 3 1 42450
  9. 5 0 0 1 42475
  10. 6 1 3 1 42535
  11. 7 1 0 1 42630
  12. 8 0 0 1 42770
  13. 9 1 3 1 42875
  14. 10 0 3 1 42725
  15. 11 0 0 1 42810
  16. 12 1 3 1 42880
  17. 13 0 0 1 42790
  18. 14 1 0 1 42715
  19. 15 0 3 1 42740
  20. 16 0 0 1 42760
  21. 17 1 3 2 42825
  22. ;run;
  23. data t2_a1
  24.           t2_a2
  25.           t2_b1
  26.           t2_b2;
  27.         set t1;
  28.         if v1 = 1 and v3 = 0 then do; clus = 'A1'; output t2_a1; end;
  29.         else if v1 = 0 and v3 = 3 then do; clus = 'A2';output t2_a2; end;
  30.         else if v1 = 0 and v3 = 0 then do; clus = 'B2';output t2_b2; end;
  31.         else if v1 = 1 and v3 = 3 then do; clus = 'B1';output t2_b1; end;
  32. run;

  33. %macro test1(var);
  34. proc sort data = t2_&var.1; by n; run;
  35. proc sort data = t2_&var.2; by n; run;
  36. data _null_;
  37.         set t2_&var.2 nobs=nn;
  38.         call symputx('n', nn);
  39.         stop;
  40. run;
  41. %put &n.;
  42. data t3_&var.(keep = new: d);
  43.         array char{&n., 2} $ _temporary_;
  44.         array num{&n.,2}  _temporary_;
  45.         retain char;
  46.         retain num;
  47.         retain start_ii end_ii left_v5 d 0;
  48.         set t2_&var.1(rename=(n=n_2 v5=v5_2 v8=v8_2 clus=clus_2));
  49.         if _n_ = 1 then do;
  50.                 do ii = 1 to &n.;
  51.                         set t2_&var.2 point = ii;
  52.                         char{ii,1} = v8;
  53.                         char{ii,2} = clus;
  54.                         num{ii,1} = n;
  55.                         num{ii,2} = v5;
  56.                 end;
  57.                 start_ii = 1;
  58.                 end_ii = 1;
  59.         end;
  60.         left_v5 = v5_2 - num{end_ii,2};
  61.         if v5_2 < num{end_ii,2} then do;
  62.                 left_v5 = 0;
  63.                 num{end_ii,2} = num{end_ii,2} - v5_2;
  64.                 d + 1;
  65.                 new_n = n_2;
  66.                 new_clus = clus_2;
  67.                 new_v5 = v5_2;
  68.                 new_v8 = v8_2;
  69.                 output;
  70.                 do ii = start_ii to end_ii;
  71.                         new_n = num{ii,1};
  72.                         new_clus = char{ii,2};
  73.                         new_v5 = num{ii,2};
  74.                         new_v8 = char{ii,1};
  75.                         output;
  76.                 end;
  77.                 start_ii = end_ii;
  78.         end;else if v5_2 = num{end_ii,2} then do;
  79.                 left_v5 = 0;
  80.                 d + 1;
  81.                 new_n = n_2;
  82.                 new_clus = clus_2;
  83.                 new_v5 = v5_2;
  84.                 new_v8 = v8_2;
  85.                 output;
  86.                 do ii = start_ii to end_ii;
  87.                         new_n = num{ii,1};
  88.                         new_clus = char{ii,2};
  89.                         new_v5 = num{ii,2};
  90.                         new_v8 = char{ii,1};
  91.                         output;
  92.                 end;
  93.                 if end_ii > &n. then stop;
  94.                 end_ii + 1;
  95.                 start_ii = end_ii;
  96.         end;else do;
  97.                 do while( left_v5 > 0 );
  98.                         end_ii + 1;
  99.                         if left_v5 < num{end_ii,2} then do;
  100.                                 left_v5 = 0;
  101.                                 num{end_ii,2} = num{end_ii,2} - v5_2;
  102.                                 d + 1;
  103.                                 new_n = n_2;
  104.                                 new_clus = clus_2;
  105.                                 new_v5 = v5_2;
  106.                                 new_v8 = v8_2;
  107.                                 output;
  108.                                 do ii = start_ii to end_ii;
  109.                                         new_n = num{ii,1};
  110.                                         new_clus = char{ii,2};
  111.                                         new_v5 = num{ii,2};
  112.                                         new_v8 = char{ii,1};
  113.                                         output;
  114.                                 end;
  115.                                 start_ii = end_ii;
  116.                         end;else if left_v5 = num{end_ii,2} then do;
  117.                                 left_v5 = 0;
  118.                                 d + 1;
  119.                                 new_n = n_2;
  120.                                 new_clus = clus_2;
  121.                                 new_v5 = v5_2;
  122.                                 new_v8 = v8_2;
  123.                                 output;
  124.                                 do ii = start_ii to end_ii;
  125.                                         new_n = num{ii,1};
  126.                                         new_clus = char{ii,2};
  127.                                         new_v5 = num{ii,2};
  128.                                         new_v8 = char{ii,1};
  129.                                         output;
  130.                                 end;
  131.                                 end_ii + 1;
  132.                                 start_ii = end_ii;
  133.                         end;else left_v5 = left_v5 - num{end_ii,2};
  134.                 end;
  135.         end;
  136. run;
  137. %mend;
  138. %test1(var = a);
  139. %test1(var = b);

  140. data t4;
  141.         format d 8. new_clus $2.;
  142.         set t3_a
  143.                 t3_b;
  144. run;
复制代码
已有 1 人评分经验 学术水平 热心指数 信用等级 收起 理由
denver + 100 + 5 + 5 + 5 多谢了,看看先

总评分: 经验 + 100  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

14
denver 发表于 2013-1-21 15:13:21
zhangzachary 发表于 2013-1-21 11:49
这个可以实现上述例子的情况。但是对于这么一种情况:(v1,v3) = (0,0) (0,0) (1,3) (1,3) 那么我就不知道后 ...
你说到的这种情况,一般是先进先出,程序会有什么不同呢?如果是后进先出呢?不好意思,终于找到牛人,就允许我一次问个够吧,学习了!
Denver大家一起读Paper系列索引贴:
https://bbs.pinggu.org/thread-1430892-1-1.html

15
denver 发表于 2013-1-21 15:14:13
maidenhan 发表于 2013-1-21 14:32
纯粹依照楼主例子做的,没有考虑任何其他的可能情况。
楼主先试试,有问题,咱们再改改。
兄弟,你太牛了,各种循环、各种宏、各种看不懂啊
Denver大家一起读Paper系列索引贴:
https://bbs.pinggu.org/thread-1430892-1-1.html

16
zhangzachary 发表于 2013-1-21 15:35:05
denver 发表于 2013-1-21 15:13
你说到的这种情况,一般是先进先出,程序会有什么不同呢?如果是后进先出呢?不好意思,终于找到牛人,就 ...
不论先进先出后进先出,这个没关系,重点在于,如果有多个(0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (1,3) (1,3) (1,3)这样的话,世界就混乱啦。。。比如假设先进先出,但是我们不知道是先进4个再进1个1个的,然后1个1个1个出来,还是进3,2,1 / 2,2,2 / 1,3,2 / 1,2,3 等等。。。简单说,我们还是需要一个变量来说明对应的买入和卖出的关系,不过呢,你的问题好像就是要找出这样的关系,于是,矛盾了,就无解了。。。
寒冰凤凰 My blog: http://blog.sina.com.cn/u/1058955485

17
denver 发表于 2013-1-21 22:50:24
zhangzachary 发表于 2013-1-21 15:35
不论先进先出后进先出,这个没关系,重点在于,如果有多个(0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (1,3) (1 ...
哈哈,别急哈,那我先研究研究哈
Denver大家一起读Paper系列索引贴:
https://bbs.pinggu.org/thread-1430892-1-1.html

18
yuerqieqie 发表于 2013-2-22 07:03:20
如果在先入先出的假设条件下, 且只考虑分组并不考虑组的顺序,这个逻辑应该不是很难。
  1. data t1 t2;
  2.         set test;

  3.     if (v1 = 1 and v3 = 0) or (v1 = 0 and v3 = 3) then output t1;
  4.         else if (v1 = 0 and v3 = 0) or (v1 = 1 and v3 = 3) then output t2;
  5. run;
  6. %macro test(indsn = , outdsn =);
  7. proc sort data = &indsn; by v3 n; run;

  8. data _tmp;
  9.         set &indsn; by v3 n;
  10.         retain cnt;
  11.         if first.v3 then cnt = 0;
  12.         cnt + v5;
  13. run;
  14. proc sort data = _tmp; by cnt v3; run;
  15.        
  16. data &outdsn;
  17.         set _tmp; by cnt v3;
  18.         retain tot_qty 0 subgrp 0;

  19.         if tot_qty = 0 then do; subgrp + 1; end;

  20.         if v3 = 0 then tot_qty = tot_qty + v5;
  21.         else if v3 = 3 then tot_qty = tot_qty - v5;

  22.         drop cnt tot_qty;
  23. run;
  24. %mend;
  25. %test(indsn = t1, outdsn = t1_grp)
  26. %test(indsn = t2, outdsn = t2_grp)

  27. data result;
  28.         set t1_grp(in = in1) t2_grp(in = in2);
  29.         if in1 then part = 1;
  30.         if in2 then part = 2;
  31. run;
复制代码
这段代码应该至少帮助分组了。

19
yuerqieqie 发表于 2013-2-22 07:16:22
考虑分组顺序也应该不难, 加上下面这段应该就可以了
  1. proc sort data = result; by part subgrp n; run;
  2. data result;
  3.         set result; by part subgrp n;
  4.         retain idx;
  5.         if first.subgrp then idx = n;
  6. run;
  7. proc sort data = result; by idx n; run;
  8. data result;
  9.         set result; by idx n;
  10.         retain grp 0;
  11.         if first.idx then grp + 1;
  12.         drop subgrp part idx;
  13. run;
复制代码

20
denver 发表于 2013-2-22 09:20:59
yuerqieqie 发表于 2013-2-22 07:16
考虑分组顺序也应该不难, 加上下面这段应该就可以了
谢谢
Denver大家一起读Paper系列索引贴:
https://bbs.pinggu.org/thread-1430892-1-1.html

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

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