SAS - 如何根据连续发生情况'总结'

时间:2018-01-25 07:50:08

标签: sas enterprise-guide

第一次发帖,所以希望有人可以帮助解决我在SAS EG中遇到的这个问题(仍在学习SAS编码,所以请善待!)

如果您看到下面的数据集片段,我正在尝试做的是根据标志为该Ref显示的连续出现次数来计算得分(pts)。

例如: 如果您为A_Flag采用Ref 505,那么该标志会连续出现两组,然后评分如下:

  • 第一个ID>第一次= 25分
  • 第二个ID>第二个实例但第一个连续实例=双倍到50个点
  • 第3个ID> 0实例= 0分
  • 第4个ID>第一次= 25分
  • 第5个ID>第二个实例但第一个连续实例=双倍到50个点
  • 第6个ID> 0实例= 0分

因此对于这个Ref A_Pts将是150分。

另一个例子: 如果您为B_Flag采用Ref 527,那么该标志会连续出现4次,因此每个ID都有取样:

  • 第一个ID> 0实例= 0分
  • 第二个ID>第一个实例= 10分
  • 第3个ID>第二个实例但第一个连续实例=双倍到20个点
  • 第4个ID>第3个实例但第2个连续实例=双倍到40个点
  • 第5个ID>第4个实例但第3个连续实例=双倍到80个点

因此对于这个参考B_Pts将是150分

我必须说数据是我想要实现的必要顺序。

我尝试过使用LAG功能,但这只能在第一个连续实例的基础上运行。

我还尝试计算一个计数 - 一个基于猫的枚举变量(Ref,A_Flag) - 但它然后错误地排序数据并且没有相应计数

希望这对那里的人有意义!

有问题的数据集:

+-----------+-----+--------+--------+--------+-------+-------+
|   date    | Ref | FormID | A_Flag | B_Flag | A_Pts | B_Pts |
+-----------+-----+--------+--------+--------+-------+-------+
| 01-Feb-17 | 505 |  74549 | A      |        |    25 |     0 |
| 01-Feb-17 | 505 |  74550 | A      |        |    25 |     0 |
| 10-Jan-17 | 505 |  82900 |        | B      |     0 |    10 |
| 13-Jan-17 | 505 |  82906 | A      |        |    25 |     0 |
| 09-Jan-17 | 505 |  82907 | A      |        |    25 |     0 |
| 11-Jan-17 | 505 |  82909 |        | B      |     0 |    10 |
| 03-Jan-17 | 527 |  62549 | A      |        |    25 |     0 |
| 04-Jan-17 | 527 |  62550 |        | B      |     0 |    10 |
| 04-Jan-17 | 527 |  76151 |        | B      |     0 |    10 |
| 04-Jan-17 | 527 |  76152 | A      | B      |    25 |    10 |
| 04-Jan-17 | 527 |  76153 | A      | B      |    25 |    10 |
+-----------+-----+--------+--------+--------+-------+-------+

期望的输出(除非有更好的建议):

+-----------+-----+--------+--------+--------+-----------+-----------+
|   date    | Ref | FormID | A_Flag | B_Flag | A_Pts_Agg | B_Pts_Agg |
+-----------+-----+--------+--------+--------+-----------+-----------+
| 01-Feb-17 | 505 |  74549 | A      |        |        25 |         0 |
| 01-Feb-17 | 505 |  74550 | A      |        |        50 |         0 |
| 10-Jan-17 | 505 |  82900 |        | B      |         0 |        10 |
| 13-Jan-17 | 505 |  82906 | A      |        |        25 |         0 |
| 09-Jan-17 | 505 |  82907 | A      |        |        50 |         0 |
| 11-Jan-17 | 505 |  82909 |        | B      |         0 |        10 |
| 03-Jan-17 | 527 |  62549 | A      |        |        25 |         0 |
| 04-Jan-17 | 527 |  62550 |        | B      |         0 |        10 |
| 04-Jan-17 | 527 |  76151 |        | B      |         0 |        20 |
| 04-Jan-17 | 527 |  76152 | A      | B      |        25 |        40 |
| 04-Jan-17 | 527 |  76153 | A      | B      |        50 |        80 |
+-----------+-----+--------+--------+--------+-----------+-----------+

所以当总计时,它将是

+-----+-----------+-----------+
| Ref | A_Pts_Agg | B_Pts_Agg |
+-----+-----------+-----------+
| 505 |       150 |        20 |
| 527 |       100 |       150 |
+-----+-----------+-----------+

1 个答案:

答案 0 :(得分:0)

试试这个:

data have;
infile cards dlm='|';
input date :date7. Ref :8. FormID :8. A_Flag :$1. B_Flag :$1. A_Pts :8.  B_Pts :8.;
format date date7.;
cards;
| 01-Feb-17 | 505 |  74549 | A      |        |    25 |     0 |
| 01-Feb-17 | 505 |  74550 | A      |        |    25 |     0 |
| 10-Jan-17 | 505 |  82900 |        | B      |     0 |    10 |
| 13-Jan-17 | 505 |  82906 | A      |        |    25 |     0 |
| 09-Jan-17 | 505 |  82907 | A      |        |    25 |     0 |
| 11-Jan-17 | 505 |  82909 |        | B      |     0 |    10 |
| 03-Jan-17 | 527 |  62549 | A      |        |    25 |     0 |
| 04-Jan-17 | 527 |  62550 |        | B      |     0 |    10 |
| 04-Jan-17 | 527 |  76151 |        | B      |     0 |    10 |
| 04-Jan-17 | 527 |  76152 | A      | B      |    25 |    10 |
| 04-Jan-17 | 527 |  76153 | A      | B      |    25 |    10 |
;
run;

data want;
  set have;
  by Ref;
  retain A_pts_agg B_pts_agg;
  if first.Ref then do;
    A_pts_agg = A_pts;
    B_pts_agg = B_pts;
  end;
  if lag(A_flag) ne (A_flag) then A_pts_agg = A_pts;
  else if A_flag = 'A' then A_pts_agg = A_pts_agg * 2;
  if lag(B_flag) ne (B_flag) then B_pts_agg = B_pts;
  else if B_flag = 'B' then B_pts_agg = B_pts_agg * 2;
run;