基于日期列对比为各ID更新Flag_End字段的SAS实现需求
SAS数据处理:按规则更新Flag_End字段
原始数据集:
ID Hired Start_date End_date Flag_Start Flag_End 0001 1-1900 01JAN2018 21DEC2018 1 2 0001 1-1900 01JAN2019 01DEC2020 2 2 0002 10-2020 26MAR2020 03MAY2020 1 2 0003 03-2021 18DEC2020 31DEC2020 1 2 ..... ....... ......... ......... ........... ...........
期望输出:
ID Hired Start_date End_date Flag_Start Flag_End 0001 1-1900 01JAN2018 21DEC2018 1 2 0001 1-1900 01JAN2019 01DEC2020 2 3 0002 03-2020 26MAR2020 03MAY2020 1 0 0003 03-2021 18DEC2020 31DEC2020 1 3 ..... ....... ......... ......... ........... ...........
规则说明
- 按ID分组排序后,按以下逻辑更新
Flag_End:- 若组内最后一条记录的
Hired为1-1900,将其Flag_End设为3; - 若
Hired对应的日期早于End_date,Flag_End设为0; - 若
Hired对应的日期晚于End_date且Hired不为1-1900,Flag_End设为3。
- 若组内最后一条记录的
SAS实现代码
/* 若原始数据集未按ID排序,先执行排序: proc sort data=original_data; by ID; run; */ data updated_data; set original_data; by ID; /* 将字符型日期转换为SAS数值日期,用于比较 */ hired_date = input(Hired, mmddyy10.); /* 适配MM-YYYY格式 */ end_date_sas = input(End_date, date9.); /* 适配DDMONYYYY格式 */ /* 保留并更新Flag_End值 */ retain new_flag_end; if first.ID then new_flag_end = Flag_End; /* 组首记录继承原始值 */ /* 按规则更新 */ if Hired = '1-1900' and last.ID then do; new_flag_end = 3; end; else if hired_date < end_date_sas then do; new_flag_end = 0; end; else if hired_date > end_date_sas and Hired ne '1-1900' then do; new_flag_end = 3; end; /* 替换原Flag_End字段 */ Flag_End = new_flag_end; /* 删除临时变量 */ drop hired_date end_date_sas new_flag_end; run;
代码说明
by ID实现分组,SAS自动生成first.ID(组首标识)和last.ID(组尾标识);input函数将字符型日期转为SAS可识别的数值日期,确保日期比较逻辑有效;retain变量用于在组内传递Flag_End值,保证非目标记录保留原始值;- 条件判断遵循规则优先级,先处理
1-1900组尾的特殊情况,再处理日期比较逻辑。
内容的提问来源于stack exchange,提问作者NewUsr_stat
相关产品推荐
相关产品推荐

