求助:基于时间区间匹配为SAS子时段数据集添加标签
解决SAS子时段继承主时段标签与角色的问题
需求说明
现有两个SAS数据集:
have1:包含ID、Start、End、Label、Role字段的主时段数据集,每个时段对应唯一标签have2:仅含ID、Start、End字段的子时段数据集,无标签信息
需要实现:当have2的子时段完全包含在have1的某时段内时,为该子时段继承对应主时段的Label和Role字段值。
示例数据集
主时段数据集 have1
data have1; input ID :$20. Start :date9. End :date9. Label :$20. Role :$20.; format start end yymmdd10.; cards; 0001 01JAN2015 30APR2015 HospitalA ex005 0001 01MAY2015 31MAY2015 HospitalA ex004 0001 01JUN2015 31DEC2015 HospitalC ex005 0002 06FEB2018 08FEB2018 HospitalA ex004 0002 09FEB2018 31AUG2018 HospitalC ex005 0002 01SEP2018 31DEC2019 HospitalC ex004 0003 01JAN2019 30SEP2019 HospitalD ex008 0003 01OCT2019 31DEC2020 HospitalD ex004 ;
子时段数据集 have2
data have2; input ID :$20. Start :date9. End :date9.; format start end yymmdd10.; cards; 0001 01JAN2015 30JAN2015 0001 31JAN2015 15FEB2015 0001 15FEB2015 30APR2015 0001 01MAY2015 15MAY2015 0001 16MAY2015 31MAY2015 0001 01JUN2015 15SEP2015 0001 16SEP2015 31DEC2015 ...... ;
期望输出数据集 output
data output; input ID :$20. Start :date9. End :date9. Label :$20. Role :$20.; format start end yymmdd10.; cards; 0001 01JAN2015 30JAN2015 HospitalA ex005 0001 31JAN2015 15FEB2015 HospitalA ex005 0001 15FEB2015 30APR2015 HospitalA ex005 0001 01MAY2015 15MAY2015 HospitalA ex004 0001 16MAY2015 31MAY2015 HospitalA ex004 0001 01JUN2015 15SEP2015 HospitalC ex005 0001 16SEP2015 31DEC2015 HospitalC ex005 ...... ;
解决方案
方法一:SQL关联匹配
直接用SAS SQL通过ID关联,同时判断子时段是否完全包含在主时段内,获取对应的Label和Role:
proc sql; create table output as select h2.ID, h2.Start, h2.End, h1.Label, h1.Role from have2 h2 left join have1 h1 on h2.ID = h1.ID and h2.Start >= h1.Start and h2.End <= h1.End order by h2.ID, h2.Start; quit;
- 用
left join可以保留所有子时段记录,未匹配到主时段的记录Label和Role会缺失;若只需要保留匹配成功的记录,换成inner join即可。
方法二:数据步合并匹配
先对两个数据集按ID和Start排序,再用数据步逻辑匹配,适合数据量较大的场景:
- 先排序数据集:
proc sort data=have1; by ID Start; run; proc sort data=have2; by ID Start; run;
- 数据步合并匹配:
data output; merge have2 (in=in_h2) have1 (in=in_h1); by ID; retain Label Role; if first.ID then call missing(Label, Role); /* 匹配到符合条件的主时段时,更新标签和角色 */ if in_h1 and have1.Start <= have2.Start and have1.End >= have2.End then do; Label = have1.Label; Role = have1.Role; end; if in_h2; format start end yymmdd10.; run;
retain语句用于保留上一条匹配到的Label和Role值,确保同一ID下的子时段能正确继承对应主时段的属性。
内容的提问来源于stack exchange,提问作者NewUsr
相关产品推荐
相关产品推荐

