首页 > 解决方案 > sas:根据日期计算行数

问题描述

我正在处理犯罪数据。现在,我有下表crimes。每行包含一个特定的罪行(例如攻击):它的实施日期(date)和犯罪者的个人 ID(person)。

date       person     
------------------------------
02JAN2017       1        
03FEB2017       1      
04JAN2018       1     --> not to be counted (more than a year after 02JAN2017)
27NOV2017       2      
28NOV2018       2     --> should not be counted (more than a year after 27NOV2017)   
01MAY2017       3
24FEB2018       3
10OCT2017       4

我感兴趣的是每个人在同一人第一次犯罪后的 1 年内是否犯过(复发=1)或未犯过(复发=0)另一次犯罪。另一个条件是必须在特定年份(此处为 2017 年)内犯下第一次犯罪。

因此,结果应如下所示:

date       person     relapse
------------------------------
02JAN2017       1           1  
03FEB2017       1           1
04JAN2018       1           1
27NOV2017       2           0 
28NOV2018       2           0 
01MAY2017       3           1
24FEB2018       3           1
10OCT2017       4           0

谁能给我一个关于如何在 SAS 中执行此操作的提示?显然,真实数据要大得多,所以我无法手动完成。

标签: sas

解决方案


一种方法是使用 DATA 逐步分组处理。

BY <var>语句设置二进制变量first.<var>last.<var>标记组中的第一行和组中的最后一行。

您似乎正在为整个组分配计算的复发标志,并且这种计算可以通过 SAS 编码人员称为 DOW 循环的方式来完成 - 一个在循环SET内包含语句的循环,以及一个将计算分配给的后续循环组中的每一行。

INTCK函数可以计算两个日期之间的年数。

例如:

data want(keep=person date relapse);
  * DOW loop computes assertion that relapse occurred;

  relapse = 0;
  do _n_ = 1 by 1 until (last.person);

    set crimes;          * <-------------- CRIMES;
    by person date;

    * check if persons first crime was in 2017;
    if _n_ = 1 and year(date) = 2017 then _first = date;

    * check if persons second crime was within 1 year of first;
    if _n_ = 2 and _first then relapse = intck('year', _first, date, 'C') < 1;
  end;

  * at this point the relapse flag has been computed, and its value
  * will be repeated for each row output;

  * serial loop over same number of rows in the group, but 
  * read in through a second SET statement;

  do _n_ = 1 to _n_;
    set crimes;              * <-------------- CRIMES;
    output;
  end;
run;

如果实际过程是根据比“2017 年第 1 次和 1 年内下一次”更细微的规则将一个人的不同时间范围分类为复发或改革,则该过程将更复杂,记账变量更多。


推荐阅读