SAS数据步骤|两个日期之间

时间:2016-02-19 19:52:00

标签: sas

可能是一个简单的问题。我有一个简单的数据集,其中包含预定的付款日期。

DATA INFORM2;
 INFORMAT previous_pmt_date scheduled_pmt_date MMDDYY10.;
 INPUT previous_pmt_date scheduled_pmt_date;
 FORMAT previous_pmt_date scheduled_pmt_date MMDDYYS10.;
DATALINES;
11/16/2015 12/16/2015
12/17/2015 01/16/2016
01/17/2016 02/16/2016

; 

我要做的是创建二进制最新行指示符。例如,如果我想知道截至2016年1月31日的最新行,我希望将第2行标记为最新行。之前我一直在做的是找出在last_pmt_date和scheduled_pmt_date之间的1/31/2016,但这对我的目的来说是不正确的。我想在数据步骤中执行此操作,而不是SQL子查询。有什么想法吗?

想要:

previous_pmt_date scheduled_pmt_date latest_row_ind
11/16/2015        12/16/2015         0
12/17/2015        01/16/2016         1
01/17/2016        02/16/2016         0

1 个答案:

答案 0 :(得分:1)

这是一个解决方案,可以在单个现有的datastep中完成所有操作而无需任何额外的排序。首先,我要稍微修改您的数据以包含帐户,因为解决方案也应该考虑到这一点:

DATA INFORM2;
 INFORMAT previous_pmt_date scheduled_pmt_date MMDDYY10.;
 INPUT account previous_pmt_date scheduled_pmt_date;
 FORMAT previous_pmt_date scheduled_pmt_date MMDDYYS10.;
DATALINES;
1 11/16/2015 12/16/2015
1 12/17/2015 01/16/2016
1 01/17/2016 02/16/2016
2 11/16/2015 12/16/2015
2 12/17/2015 01/16/2016
2 01/17/2016 02/16/2016

; 
run;

指定截止日期:

%let cutoff_date = %sysfunc(mdy(1,31,2016));

此解决方案使用this question中的方法将下一行数据中的变量保存到当前行中。如果需要,您可以在最后删除变量(我已经为了测试目的而进行了注释)。

data want;
  set inform2 end=eof;
  by account scheduled_pmt_date; 

  recno = _n_ + 1;

  if not eof then do;
    set inform2 (keep=account previous_pmt_date scheduled_pmt_date
                 rename=(account            = next_account 
                         previous_pmt_date  = next_previous_pmt_date
                         scheduled_pmt_date = next_scheduled_pmt_date)
                ) point=recno;
  end;
  else do;
    call missing(next_account, next_previous_pmt_date, next_scheduled_pmt_date);
  end;

  select;
    when ( next_account eq account and next_scheduled_pmt_date gt &cutoff_date ) flag='a';
    when ( next_account ne account ) flag='b';
    otherwise flag = 'z';
  end;

  *drop next:;

run;

此方法通过使用数据集中的当前观察(通过_n_获得)并向其添加1来进行下一次观察。然后,我们使用带有set选项的第二个point=语句加载下一个观察值并同时重命名变量,以便它们不会覆盖当前变量。

然后我们使用一些逻辑来标记必要的记录。我不是100%的逻辑,因此我提供了一些示例逻辑并使用不同的标志来显示正在触发的逻辑。

一些说明......

by声明并非严格必要,但我将其包括在内(a)确保数据正确排序,以及(b)帮助未来的读者了解datastep的意图因为一些逻辑需要这种排序顺序。

call missing语句只是用来清理日志。当你的变量没有得到指定值时,SAS不喜欢它,这将在最后一次观察时发生,所以这就是为什么我们包括这个。评论它看看会发生什么。

end=eof语法基本上创建了一个名为eof的临时变量,当我们到达该set语句的最后一个观察值时,该变量的值为1。我们只是用它来确定我们是否在最后一行。

最后但非常重要的是,请确保在第二个数据集中加载时只保留所需的变量,否则您将覆盖原始数据中的现有变量。