SAS跨数据集日期区间校验:生成Flag标记字段的实现方法问询
跨SAS数据集日期区间比对并生成标记字段的实现方案
输入数据集
DB1数据集
data DB1; input ID :$20. Reference_date :date9. Discharge :date9.; format Reference_date Discharge date9.; cards; 0001 14JUN2017 19JUN2017 0002 12MAR2016 17MAR2016 0003 01MAY2016 05MAY2016 0004 19MAR2017 22MAR2017 0005 10MAR2017 22MAR2017 0007 10OCT2015 14OCT2015 ;
DB2数据集
data DB2; input ID :$20. Discharge_new :date9.; format Discharge_new date9.; cards; 0001 21JUN2017 0002 13MAR2016 0003 04MAY2016 0004 19MAR2017 0005 22MAR2017 0006 27JUN2022 0007 18OCT2015 ;
需求说明
- 对DB2中的每个ID,匹配DB1中对应ID的
Reference_date和Discharge日期 - 若
Discharge_new落在[Reference_date, Discharge]闭区间内,Flag设为1;否则设为0 - DB2中未在DB1出现的ID,
Flag设为缺失值 - 最终生成目标数据集DB3
实现方案
方法一:Proc SQL 左连接实现
proc sql; create table DB3 as select b.ID, b.Discharge_new, case when a.ID is missing then . when b.Discharge_new between a.Reference_date and a.Discharge then 1 else 0 end as Flag from DB2 as b left join DB1 as a on b.ID = a.ID order by b.ID; quit; /* 为日期字段添加格式,保持输出与示例一致 */ proc datasets library=work nolist; modify DB3; format Discharge_new date9.; run; quit;
方法二:Data步 Merge 实现
/* 先对两个数据集按ID排序,确保merge匹配正确 */ proc sort data=DB1; by ID; run; proc sort data=DB2; by ID; run; data DB3; merge DB2 (in=b) DB1 (in=a); by ID; /* 仅保留DB2中的记录 */ if b then do; /* 根据是否匹配到DB1的ID设置Flag */ if a then do; if Discharge_new between Reference_date and Discharge then Flag=1; else Flag=0; end; else Flag=.; end; /* 只保留需要的字段 */ keep ID Discharge_new Flag; format Discharge_new date9.; run;
代码说明
Proc SQL方法:
- 以DB2为基础做左连接,确保所有DB2的记录都被保留,同时匹配DB1中同ID的日期字段
- 通过
case分支逻辑直接判断三种情况:无匹配ID设缺失值、日期在区间内设1、否则设0 - 最后按ID排序,保证输出顺序与示例一致
Data步Merge方法:
- 先排序是merge操作的前提,确保同ID的记录能正确对齐
- 用
in选项标记记录来源,只处理DB2的记录 - 分情况判断:匹配到DB1则校验日期区间,未匹配则设Flag为缺失值
目标输出DB3
data DB3; input ID :$20. Discharge_new :date9. Flag :$20.; format Discharge_new date9.; cards; 0001 21JUN2017 0 0002 13MAR2016 1 0003 04MAY2016 1 0004 19MAR2017 1 0005 22MAR2017 1 0006 27JUN2022 . 0007 18OCT2015 0 ;
内容的提问来源于stack exchange,提问作者NewUsr_stat
相关产品推荐
相关产品推荐

