SAS数据集筛选:保留exp_date处于code271与code272日期区间内的记录
解决SAS数据集日期区间筛选问题
需求说明
现有包含acct_num、code、code_date和exp_date字段的SAS数据集,需按以下规则筛选记录:
- 针对每个
acct_num,获取其对应的code=271的code_date与code=272的code_date组成的日期区间 - 保留
exp_date处于该区间内的所有记录,移除不符合条件的记录(如示例中acct_num=3333的所有记录,因其exp_date不在对应区间内)
输入数据集代码
首先需正确读入原始数据,将日期字段转换为SAS日期格式:
data input_data; input acct_num code code_date :date9. exp_date :date9.; format code_date exp_date date9.; DATALINES; 1111 271 23FEB2020 27FEB2020 1111 272 13MAR2020 21FEB2020 2222 271 17MAR2020 28MAY2021 2222 271 17MAR2020 29MAY2021 2222 272 31DEC2021 02JUN2021 2222 272 31DEC2021 02JUN2021 3333 271 23JUL2018 02JUN2022 3333 272 21SEP2018 02JUN2022 ; run;
解决方案
方法1:PROC SQL实现
通过子查询获取每个账户的code=271和code=272对应日期,关联主表完成区间判断:
proc sql; create table filtered_data as select a.* from input_data a inner join ( select acct_num, max(case when code=271 then code_date end) as start_date format=date9., max(case when code=272 then code_date end) as end_date format=date9. from input_data where code in (271,272) group by acct_num ) b on a.acct_num = b.acct_num where a.exp_date between b.start_date and b.end_date; quit;
方法2:DATA步+合并实现
分步提取日期区间、合并后关联主表筛选:
/* 提取code=271的日期 */ data code271; set input_data; where code=271; keep acct_num code_date; rename code_date=start_date; run; /* 提取code=272的日期 */ data code272; set input_data; where code=272; keep acct_num code_date; rename code_date=end_date; run; /* 按账户合并日期区间 */ data date_ranges; merge code271 code272; by acct_num; format start_date end_date date9.; run; /* 关联主表并筛选符合条件的记录 */ data filtered_data; merge input_data date_ranges; by acct_num; if exp_date between start_date and end_date; run;
结果说明
运行上述任意一种方法后,filtered_data数据集将移除acct_num=3333的所有记录,其余符合日期区间要求的记录会被保留。
内容的提问来源于stack exchange,提问作者Ezio_Auditore
相关产品推荐
相关产品推荐

