Sas 基于公共数据字段比较不同行之间的开始/结束日期

Sas 基于公共数据字段比较不同行之间的开始/结束日期,sas,Sas,SAS 9.4 示例数据集 ╔═════════╦═══════╦════════════╦══════════╗ ║ subject ║ event ║ start_date ║ end_date ║ ╠═════════╬═══════╬════════════╬══════════╣ ║ s1 ║ e1 ║ 2-Mar-19 ║ 1-Jun-19 ║ ║ s2 ║ e1 ║ 1-Mar-19 ║ 1-May-19 ║ ╚═════

SAS 9.4

示例数据集

╔═════════╦═══════╦════════════╦══════════╗  
║ subject ║ event ║ start_date ║ end_date ║  
╠═════════╬═══════╬════════════╬══════════╣  
║ s1      ║ e1    ║ 2-Mar-19   ║ 1-Jun-19 ║  
║ s2      ║ e1    ║ 1-Mar-19   ║ 1-May-19 ║  
╚═════════╩═══════╩════════════╩══════════╝ 
预期产出:

╔═════════╦═══════╦════════════╦══════════╦════════════╗  
║ subject ║ event ║ start_date ║ end_date ║ query_text ║  
╠═════════╬═══════╬════════════╬══════════╬════════════╣   
║ s1      ║ e1    ║ 1-Mar-19   ║ 1-Jun-19 ║ error?     ║  
║ s2      ║ e1    ║ 1-Mar-19   ║ 1-May-19 ║ error?     ║  
╚═════════╩═══════╩════════════╩══════════╩════════════╝  
我想返回所有具有相同“事件”且其中一个具有较早“开始日期”的“结束日期”大于另一个具有较晚“开始日期”的“开始日期”的事件

此处,受试者“s2”的“开始日期”早于“s1”,但“s2”的“结束日期”晚于“s1”的“开始日期”,因此将返回这两个数据

这就是我目前所拥有的,但我不确定如何确保我所比较的内容具有相同的“事件”:

data Out_2;   
/* set relevant dataset */   
if input(compress(end_date,"/"), ??date9.) > input(compress(start_date,"/"), ??date9.);  

/* do something */  

run;

感谢

在数据步骤中处理分组行的方法是按键排序,然后在数据步骤中使用
按键字段(
在您的示例中为event
),
保留组中前几行的数据,使用
if first.key\u字段
if last.key\u字段
标识组的第一行和最后一行

如果你每个活动最多有两个主题,那就很容易了。如果有更多数据,则必须编写重复代码以保留第一行、第二行等的值,或者将数据保留到数组中

因此,我放弃了数据步骤,转而选择SQL,它可以让您轻松地完成这一任务:

proc sql;
    create table result as
    select i1.*
      from example_input i1,
           example_input i2
     where i1.event = i2.event
       and i1.subject ^= i2.subject
       and (
             (i1.start_date < i2.start_date and
              i1.end_date > i2.start_date
             ) 
           or /* the other way around */
             (i2.start_date < i1.start_date and
              i2.end_date > i1.start_date
             )
           )
   ; /* untested - I don't have SAS handy */
quit;

预期输出中
s1
1-Mar-19
开始日期是否输入错误?谢谢回复!看起来这段代码几乎让我达到了目的,但是SELECTI1.*只给了我重复的代码。但是在使用Distinct之后,它也会给我一个条目(以OP为例,它只会给我subject s1,而不是subject s2)。我想让s1和s2主题返回,嗯,你真的是说重复的吗?在您提供的确切示例数据集上(假设它具有“SAS日期值”,而不是“开始日期”和“结束日期”中的字符串)?我很好奇i1.*和i2.*的输出是什么我已经检查了SQL本身是否在做我想要它做的事情,并添加了一个到SQLFIDLE的链接。哦,等等,不,是的,你的代码工作正常,我不知道昨晚为什么会有重复的代码。尽管我的日期格式类似于“05JAN2019”,但输出似乎是正确的,或者这是SQL可以进行日期比较的格式吗?谢谢关于日期值,请确保数据集中的日期变量具有数字类型,而不是字符类型。如果是,您会看到“2019年1月5日”,因为日期列上定义了
DATE9.
格式;大多数SAS代码,包括我发布的代码,都是在未格式化的值()上运行的,因此日期比较将按预期工作。
| subject | event | start_date | end_date   |
| ------- | ----- | ---------- | ---------- |
| s1      | e1    | 2019-03-02 | 2019-06-01 |
| s2      | e1    | 2019-03-01 | 2019-05-01 |