使用滞后功能按行检索数据

时间:2019-03-08 10:01:33

标签: sql sas dataset lag

早上好。 我有这个数据集:

Appendix | Change_Serial_Number| Status     | Duration | Mileage  | Service
20101234        0                   .            60       120000       Z
20101234        1                 Proposed       48       110000       Z
20101234        2                 Activated      24        90000       Z
20101234        3                 Proposed       60       120000       Z
20101234        4                 Proposed       50       160000       B
20101234        5                 Activated      36       110000       B

每行都是可以激活的变体,或仅在状态像空白或先前激活的变体的第一行中提出的变体。 我需要这张桌子:

Appendix | Change_Serial_Number| Status     | Duration | Mileage  | Service |Duration_Prev| Mileage_prev |
20101234        0                   .            60       120000       Z        .
20101234        1                 Proposed       48       110000       Z        60              120000
20101234        2                 Activated      24        90000       Z        60              120000
20101234        3                 Proposed       60       120000       Z        24              90000
20101234        4                 Proposed       50       160000       B        24              90000
20101234        5                 Activated      36       110000       B        24              90000

只有在没有激活变体的情况下,我才需要将每个变体的持续时间,里程和服务与之前激活的或初始条件进行比较。

我尝试使用滞后函数来检索上一行的数据,但是我需要检索3字段的数据,并且仅从上次激活的变化中检索数据,或者如果没有,则从初始条件中检索数据。

我使用了以下代码:

proc sort data=db_rdg;
       by Appendix Change_Serial_Number descending Change_Serial_Number;
  run;

  data db_rdg2;
       set db_rdg;
  by Appendix;
  Duration_prev=lag(Duration);
  if first. Appendix then Durata_prev =.;
  run;

使用此代码,我只能从先前的行中(而不是从先前活动的行或第一个条件中)检索数据,并且只能检索持续时间变量(不能同时获取持续时间,里程和服务)的数据。

我希望我已经足够清楚了:)

谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

lag()函数仅对于处理之前来自特定数量观察值的值非常有用。在这种情况下,您不知道要使用的值是来自先前的观察值还是来自先前的五个或六个观察值,因此,应该使用其他变量lag()来代替RETAIN并在适当时更新其值:

data db_rdg2;
  retain duration_prev .;
  set db_rdg;
  by Appendix;
  if first.Appendix or status = 'Activated' then duration_prev = duration;
run;

RETAIN语句允许duration_prev保留其值,作为从输入中读取的每个新观察值,而不是重置为丢失。

http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000214163.htm

答案 1 :(得分:0)

您不是要使用LAG从上一行中检索duration,而是要将激活状态跟踪变量(持续时间,里程和序列号)存储在一个变量中,该变量在之后保留并更新 的显式输出。

在这两个示例代码中,我可能会想知道先前激活的更改数量,因此我将这些代码添加到了跟踪序列中。

data have; input
Appendix   Change_Serial_Number   Status $     Duration  Mileage   Service $;
datalines;
20101234        0                   .            60       120000       Z
20101234        1                 Proposed       48       110000       Z
20101234        2                 Activated      24        90000       Z
20101234        3                 Proposed       60       120000       Z
20101234        4                 Proposed       50       160000       B
20101234        5                 Activated      36       110000       B
run;

* NOTE: _APA suffix means @ prior activate;

* version 1;
* implicit loop with by group processing means ;
* explicit first. test needed in order to reset the apa tracking variables;

data want;
  set have;
  by appendix;

  if first.appendix then do;
     length csn_apa dur_apa mil_apa 8;
     call missing(csn_apa, dur_apa, mil_apa);    
  end;

  output;

  if status in (' ' 'Activate') then do;
    csn_apa = change_serial_number;
    dur_apa = duration;
    mil_apa = mileage;
  end;

  retain csn_apa dur_apa mil_apa;
run;

* version 2;
* DOW version;
* explicit loop over group means first. handling not explicitly needed;
* implicit loop performs tracking variable resets;
* retain not needed because output and tracking variables modified;
* within current iteration of implicit loop;

data want2;
  do until (last.appendix);
    set have;
    by appendix;

    output;

    if status in (' ' 'Activate') then do;
      csn_apa = change_serial_number;
      dur_apa = duration;
      mil_apa = mileage;
    end;
  end;
run;