基于account_number判断交易日期是否处于前两个账单日期区间
SAS 数据处理:筛选交易日期在账号前两个账单日期区间的记录
需求说明
针对每个账号,提取其前两个账单日期,判断交易日期是否处于这两个日期构成的区间内;仅保留满足条件的账号的前两行数据,移除不满足条件的账号的所有行及账号的多余行。
输入数据
data input_data; input acct_num billing_date :date9. tran_date :date9.; format billing_date tran_date date9.; DATALINES; 1111 23FEB2020 27FEB2020 1111 23MAR2020 27FEB2020 2222 17MAR2020 22MAR2020 2222 27APR2020 22MAR2020 2222 27MAY2020 22MAR2020 3333 23JUL2018 02JUN2022 3333 23AUG2018 02JUN2022 ; run;
注:修正了原输入中biiling_date的拼写错误,改为billing_date以确保日期字段正常解析
解决方案代码
/* 第一步:标记每个账号的行号,提取前两个账单日期并判断交易日期是否在区间内 */ data temp; set input_data; by acct_num; retain first_bill last_bill; if first.acct_num then do; first_bill = billing_date; last_bill = .; row_num = 1; end; else row_num + 1; /* 记录第二个账单日期作为区间上限 */ if row_num = 2 then last_bill = billing_date; /* 计算前两个账单日期的有效区间(取最小和最大值) */ bill_min = min(first_bill, coalesce(last_bill, first_bill)); bill_max = max(first_bill, coalesce(last_bill, first_bill)); /* 判断交易日期是否处于区间内 */ tran_in_range = (tran_date >= bill_min) and (tran_date <= bill_max); run; /* 第二步:筛选满足条件的账号的前两行记录 */ data output_data; set temp; by acct_num; /* 仅保留交易日期在区间内且为账号前两行的记录 */ if tran_in_range and row_num <= 2; run; /* 查看最终结果 */ proc print data=output_data noobs; run;
代码说明
- 分组标记与区间计算:通过
by acct_num分组,用retain保留每个账号的第一个账单日期,遍历到第二行时记录第二个账单日期,进而计算出前两个账单日期的区间范围。 - 交易日期判断:生成
tran_in_range标记,判断当前账号的交易日期是否落在前两个账单日期的区间内。 - 筛选结果:仅保留
tran_in_range为真且行号不超过2的记录,自动过滤掉不满足条件的账号(如3333)及账号的多余行(如2222的第三行)。
期望输出
acct_num billing_date tran_date 1111 23FEB2020 27FEB2020 1111 23MAR2020 27FEB2020 2222 17MAR2020 22MAR2020 2222 27APR2020 22MAR2020
内容的提问来源于stack exchange,提问作者Ezio_Auditore
相关产品推荐
相关产品推荐

