如何在SAS中处理纵向月度客户数据,生成永久逾期标记ever_missed?
SAS生成客户永久逾期标记(ever_missed)方案
需求说明
给定垂直堆叠的月度客户数据(每个客户每月一条记录),需生成ever_missed字段:只要该客户任意月份出现missed_pay=1,则该客户所有记录的ever_missed永久设为1;从未逾期则保持0。
示例输出数据
| Cust Id | Month | missed_pay | ever_missed |
|---|---|---|---|
| 1234 | Jan | 0 | 0 |
| 1234 | Feb | 0 | 0 |
| 1234 | Mar | 1 | 1 |
| 1234 | Apr | 0 | 1 |
| 5678 | Jan | 1 | 1 |
| 5678 | Feb | 0 | 1 |
| 5678 | Mar | 1 | 1 |
| 5678 | Apr | 0 | 1 |
实现方法
方法1:DATA步+RETAIN(按客户遍历记录)
这种方法适合需要按月份顺序处理的场景,先确保同客户的记录连续:
/* 按客户ID排序,保证同客户记录连续 */ proc sort data=original_data; by Cust_Id Month; run; /* 生成ever_missed标记 */ data final_data; set original_data; by Cust_Id; retain ever_missed 0; /* 保留变量值,不自动重置 */ /* 每个客户第一条记录初始化ever_missed为0 */ if first.Cust_Id then ever_missed = 0; /* 只要当前或之前月份有逾期,就把标记设为1 */ if missed_pay = 1 then ever_missed = 1; run;
by Cust_Id用来识别客户分组,first.Cust_Id触发每个客户的初始化动作。retain让ever_missed的值在同客户的记录间传递,一旦设为1就不会再变回0。
方法2:PROC SQL(无需排序,直接客户级计算)
如果不需要按月份顺序处理,用SQL分组计算更简洁:
proc sql; create table final_data as select a.*, case when b.has_missed = 1 then 1 else 0 end as ever_missed from original_data a left join ( /* 计算每个客户是否有过逾期 */ select Cust_Id, max(missed_pay) as has_missed from original_data group by Cust_Id ) b on a.Cust_Id = b.Cust_Id; quit;
- 子查询先按客户分组,用
max(missed_pay)判断该客户是否存在逾期记录(结果为1表示有,0表示无)。 - 主查询将原数据与客户级结果关联,统一设置所有记录的
ever_missed标记。
内容的提问来源于stack exchange,提问作者Kev
相关产品推荐
相关产品推荐

