【问题标题】:SAS : Understanding lag function to retain dates based on work progessSAS:了解滞后功能以根据工作进度保留日期
【发布时间】:2017-04-27 15:58:22
【问题描述】:

我有一个工作进度表要制作。 因此,如果我们有一个工作进度为新的表,进度、开始、结束和重新启动,并且一些规则是:

  1. 首先,当工作是 NEW 时,开始日期设置为 '1/01/2013',其他后续工作进度设置相同。

  2. 其次,如果工作是 END-ed 并再次 ADD-ed,则开始日期设置为 '01/01/2016'(下图:Work_id=3)。以下 work_progress 必须具有相同的值。

  3. 最后一种情况,当工作 (work_id:1,2) 重新启动时,开始日期设置为收到工作的开始时间。以后的日期必须遵循相同的 '01/05/2017'。下面是我的逻辑输出的数据集。

文本缩进

+---------+---------------+-------------------+------------+------------+
| work_id | work_progress |   received_date   |   start    |    end     |
+---------+---------------+-------------------+------------+------------+
|       1 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       1 | PROGRESS      | December 25, 2016 | 01/01/2013 | 31/12/2020 |
|       1 | END           | January 1, 2017   | 01/01/2013 | 02/02/2017 |
|       1 | RESTART       | February 5, 2017  | 01/05/2017 | 31/12/2020 |
|       1 | PROGRESS      | March 20, 2017    | 01/01/2013 | 31/12/2020 |
|       2 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       2 | PROGRESS      | December 25, 2016 | 01/01/2013 | 31/12/2020 |
|       2 | END           | January 1, 2017   | 01/01/2013 | 31/12/2020 |
|       2 | RESTART       | February 5, 2017  | 01/05/2017 | 31/12/2020 |
|       2 | PROGRESS      | March 20, 2017    | 01/01/2013 | 31/12/2020 |
|       3 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       3 | END           | December 25, 2016 | 01/01/2013 | 02/02/2017 |
|       3 | NEW           | January 1, 2017   | 01/01/2016 | 31/12/2020 |
|       3 | END           | February 5, 2017  | 01/01/2013 | 02/02/2017 |
|       3 | END           | March 20, 2017    | 01/01/2013 | 03/03/2017 |
|       3 | END           | April 21, 2017    | 01/01/2013 | 04/04/2017 |
+---------+---------------+-------------------+------------+------------+  

我的输出实际上是什么:

+---------+---------------+-------------------+------------+------------+
| work_id | work_progress |   received_date   |   start    |    end     |
+---------+---------------+-------------------+------------+------------+
|       1 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       1 | PROGRESS      | December 25, 2016 | 01/01/2013 | 31/12/2020 |
|       1 | END           | January 1, 2017   | 01/01/2013 | 02/02/2017 |
|       1 | RESTART       | February 5, 2017  | 01/05/2017 | 31/12/2020 |
|       1 | PROGRESS      | March 20, 2017    | 01/05/2017 | 31/12/2020 |
|       2 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       2 | PROGRESS      | December 25, 2016 | 01/01/2013 | 31/12/2020 |
|       2 | END           | January 1, 2017   | 01/01/2013 | 31/12/2020 |
|       2 | RESTART       | February 5, 2017  | 01/05/2017 | 31/12/2020 |
|       2 | PROGRESS      | March 20, 2017    | 01/05/2017 | 31/12/2020 |
|       3 | NEW           | November 19, 2016 | 01/01/2013 | 31/12/2020 |
|       3 | END           | December 25, 2016 | 01/01/2013 | 02/02/2017 |
|       3 | NEW           | January 1, 2017   | 01/01/2016 | 31/12/2020 |
|       3 | END           | February 5, 2017  | 01/01/2016 | 02/02/2017 |
|       3 | END           | March 20, 2017    | 01/01/2016 | 02/02/2017 |
|       3 | END           | April 21, 2017    | 01/01/2016 | 02/02/2017 |
+---------+---------------+-------------------+------------+------------+    

要求:

  1. 当 NEW 和 重新开始。
  2. 在 work_id=3 和 work_progress=END 中的结束日期。三月和四月 两者的结束日期都应该是 2 月。

我需要在这里使用滞后来保留开始和结束日期。除了这个滞后使用部分外,我已经实现了一半的问题逻辑。 部分sas代码:

data m_out_ds;
 set m_in_ds;
 by work_id work_received_date;
 /*--------
 Some logic to derive my rules, that gave output, first table above.
  ----------*/
 prevstart = lag(start);
 prevend = lag(end); 
 prev_work_progress = lag(work_progress);

 if work_progress = 'END' and prev_work_progress = 'END' then end = prevend;

/*---This gave 02/02/2017 for march received date only, 
  but we require for april too, obvious the work has ended.----*/

if work_progress = 'PROGRESS' and prev_work_progress ='RESTART' 
  then start = prevstart; 

/*---This however worked---*/

run;

如果您无法理解这一点,请告诉我。 谢谢。

【问题讨论】:

  • 您是否尝试仅使用保留变量而不是尝试使用 LAG() 函数来提供帮助?
  • 嗨@tom!按 work_id 和 recieved_date 排序不允许从这里获得帮助。
  • 第一组数据是输入吗?或者在输出上进行一些尝试?如果没有,您可以发布输入。
  • @tom,对输出进行了一些尝试。恐怕我现在做不到。缩进会让事情更清楚吗?我想要第二张桌子,就是这样。
  • 你能用示例数据解释一下规则吗?为什么第 5 行(第一个 ID 值的最后一行)中的 START 从 2013-01-01 更改为 2017-05-01?这个新日期从何而来?是因为它是上一个记录的开始吗?还是之前的记录具有 RESTART 类型是否重要?之前的值在记录 5 上的当前值之后是否重要?

标签: sas lag retain


【解决方案1】:

这似乎与您的数据相匹配,但我仍然不确定我是否理解规则。首先让我们把你的文本变成数据。

data have ;
  infile cards dsd dlm='|' truncover ;
  row+1;
  length work_id 8 work_progress $8 received_date start end 8 ;
  informat received_date anydtdte. start end ddmmyy.;
  format received_date  start end yymmdd10.;
  input work_id -- end ;
CARDS;
   1|NEW     | November 19, 2016|01/01/2013|31/12/2020 
   1|PROGRESS| December 25, 2016|01/01/2013|31/12/2020 
   1|END     | January 1, 2017  |01/01/2013|02/02/2017 
   1|RESTART | February 5, 2017 |01/05/2017|31/12/2020 
   1|PROGRESS| March 20, 2017   |01/01/2013|31/12/2020 
   2|NEW     | November 19, 2016|01/01/2013|31/12/2020 
   2|PROGRESS| December 25, 2016|01/01/2013|31/12/2020 
   2|END     | January 1, 2017  |01/01/2013|31/12/2020 
   2|RESTART | February 5, 2017 |01/05/2017|31/12/2020 
   2|PROGRESS| March 20, 2017   |01/01/2013|31/12/2020 
   3|NEW     | November 19, 2016|01/01/2013|31/12/2020 
   3|END     | December 25, 2016|01/01/2013|02/02/2017 
   3|NEW     | January 1, 2017  |01/01/2016|31/12/2020 
   3|END     | February 5, 2017 |01/01/2013|02/02/2017 
   3|END     | March 20, 2017   |01/01/2013|03/03/2017 
   3|END     | April 21, 2017   |01/01/2013|04/04/2017 
;
data want ;
  infile cards dsd dlm='|' truncover ;
  row+1;
  length work_id 8 work_progress $8 received_date start end 8 ;
  informat received_date anydtdte. start end ddmmyy.;
  format received_date  start end yymmdd10.;
  input work_id -- end ;
CARDS;
   1|NEW        |November 19, 2016|01/01/2013|31/12/2020 
   1|PROGRESS   |December 25, 2016|01/01/2013|31/12/2020 
   1|END        |January 1, 2017  |01/01/2013|02/02/2017 
   1|RESTART    |February 5, 2017 |01/05/2017|31/12/2020 
   1|PROGRESS   |March 20, 2017   |01/05/2017|31/12/2020 
   2|NEW        |November 19, 2016|01/01/2013|31/12/2020 
   2|PROGRESS   |December 25, 2016|01/01/2013|31/12/2020 
   2|END        |January 1, 2017  |01/01/2013|31/12/2020 
   2|RESTART    |February 5, 2017 |01/05/2017|31/12/2020 
   2|PROGRESS   |March 20, 2017   |01/05/2017|31/12/2020 
   3|NEW        |November 19, 2016|01/01/2013|31/12/2020 
   3|END        |December 25, 2016|01/01/2013|02/02/2017 
   3|NEW        |January 1, 2017  |01/01/2016|31/12/2020 
   3|END        |February 5, 2017 |01/01/2016|02/02/2017 
   3|END        |March 20, 2017   |01/01/2016|02/02/2017 
   3|END        |April 21, 2017   |01/01/2016|02/02/2017 
;

现在让我们尝试转换它。

data try ;
  set have ;
  by work_id;
  retain new_start new_end ;
  format new_start new_end yymmdd10.;
  if first.work_id then call missing(of new_start new_end);
  if work_progress in ('NEW','RESTART') then new_start=start ;
  start=coalesce(new_start,start);
  if work_progress in ('END') then do;
    if missing(new_end) then new_end=end ;
    end=coalesce(new_end,end);
  end;
run;
proc compare data=want compare=try;
  id row;
run;
proc print data=try; run;

【讨论】:

  • 这很有意义。输出是我要找的。但是,如果我能让您了解 received_date 是如何与 work_id 相关联的,我可以确定这可以完美运行。 id 1,2,3 均在 2016-11-19(2016 年 11 月 19 日)收到,并有相应状态,作品按月收到。工作生命周期:NEW-PROGRESS-END-/-END 等等。如果你明白这一点,逻辑会更合理。你找我吗?在此感谢您的帮助。
猜你喜欢
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多