编写当前的下一行数据

时间:2015-08-05 12:54:21

标签: sas

如果我想从下一行复制数据,该怎么办? 例如,客户A在01JAN2015开始他的当前旅行,并在15JAN2015开始下一次旅行。因此,他此次旅行的终点旅行日期将是2015年1月14日,也就是他下次旅行开始的前一天。我可以为结束旅行日期编写什么脚本?

3 个答案:

答案 0 :(得分:1)

由于SAS中没有lead()功能,您可以按照Vasilij的回答将数据按日期降序排序并使用lag()然后再重新排序,或者您可以执行此操作'前瞻合并'。

示例:

proc sort data=have ;
  by customer date_start ;
run ;

data want ;
  merge have
        have (firstobs=2 rename=(date_start=next_date customer=next_customer)) ;
  if customer = next_customer then do ;
    date_end = next_date ;
  end ;

  format date_end date7. ;
  drop next_: ;
run ;

答案 1 :(得分:0)

以下代码可以满足您的要求。

它按降序对数据进行排序,以便使用LAG()函数。这样,任何以前的记录实际上都是您未来的记录,您可以使用它来计算出您需要的数据点。最后一个PROC SORT按原始顺序对数据进行排序。

注意:我没有考虑到不同的客户。您可能希望引入一些BY GROUP处理,以确保您不会为下一个客户采取下一个旅行日期。

data have; 
input customer $ date_start date7.; 
format date_start date7.;
datalines; 
A 01JAN15
A 15JAN15
;

PROC SORT data=have;
by customer Descending date_start ;
RUN; 

data want; 
set have; 
by customer Descending date_start ; 
format date_end date7.;
date_end = lag(date_start)-1; 
RUN; 

PROC SORT data=want;
by customer date_start ;
RUN;

答案 2 :(得分:0)

lag()是一个可怕的误称功能,与前一行'无关。应该几乎总是避免。它经常会产生错误,很难发现错误。在某些罕见的情况下使用它是有意义的。这不是其中的一个。我真的希望人们不再推荐使用它。 [/ end rant]。

相反,请考虑使用以下方法之一。

1)point=方法(不确定是否有此名称)。有些注意事项,请务必在第二个set语句中保留所需的变量,而不是更多。重命名它们,以便它们不会覆盖现有的变量值。

data want;

  set sashelp.class end=last;  

  * GET THE NAME FROM THE NEXT ROW OF DATA;
  if not last then do;
    recno=_n_+1;
    set sashelp.class(keep=name rename=(name=next_name)) point=recno;
  end;
  else do;
    call missing(next_name);
  end;

run;

2)retain方法:

* REVERSE THE ORDER OF THE DATA;
proc sort data=sashelp.class out=have;
  by descending name;
run;

* KEEP TRACK OF THE PRIOR RECORDS NAME AS WE ITERATE ACROSS OBSERVATIONS;
data have2;
  set have;
  length next_name $8;
  retain next_name '';
  output; 
  next_name = name;
run;

* SORT THE DATA BACK TO ITS ORIGINAL ORDER;
proc sort data=have2 out=want;
  by name;
run;

3)Chris J的回答中提出的前瞻合并方法。