如果我想从下一行复制数据,该怎么办? 例如,客户A在01JAN2015开始他的当前旅行,并在15JAN2015开始下一次旅行。因此,他此次旅行的终点旅行日期将是2015年1月14日,也就是他下次旅行开始的前一天。我可以为结束旅行日期编写什么脚本?
答案 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的回答中提出的前瞻合并方法。