如何用Do循环(多ID行)结合条件语句生成聚合SAS数据集?
SAS按ID聚合生成标记字段的实现方法
需求说明
现有初始SAS数据集finance,需按id聚合生成每个ID仅一行的数据集,规则如下:
- 若该ID下任意一行满足
loan1 < 80000,则conc取值为'level1' - 若该ID下任意一行满足
loan2 < 80000且home = 'new',则borrowcap取值为'high'
实现方法
方法1:PROC SQL 聚合查询
利用SQL的CASE WHEN结合聚合函数MAX,直接按ID分组判断是否存在满足条件的行:
proc sql; create table finance_final as select id, max(case when loan1 < 80000 then 'level1' else '' end) as conc length=6, max(case when loan2 < 80000 and home='new' then 'high' else '' end) as borrowcap length=4 from finance group by id; quit;
- 原理:
CASE WHEN将满足条件的行标记为目标值,否则为空字符串;MAX函数会保留组内非空的目标值(只要有一行满足条件,就会得到对应的标记)。
方法2:DATA步BY组处理
先对数据集按ID排序,再通过RETAIN保留标记变量,遍历组内每行更新标记,最后输出每组结果:
/* 按ID排序,确保BY组分组正确 */ proc sort data=finance out=finance_sorted; by id; run; data finance_final; set finance_sorted; by id; /* 保留标记变量,使其值跨行传递 */ retain conc borrowcap; /* 每组第一行初始化标记为空 */ if first.id then do; conc = ''; borrowcap = ''; end; /* 检查条件,满足则更新标记(一旦设置不会被后续行覆盖) */ if loan1 < 80000 then conc = 'level1'; if loan2 < 80000 and home='new' then borrowcap = 'high'; /* 每组最后一行输出最终结果 */ if last.id then output; /* 仅保留需要的变量 */ keep id conc borrowcap; run;
- 原理:
RETAIN让标记变量的值在数据步循环中保留;遍历组内每行时,只要有一行满足条件就设置标记,后续行不会清空该标记;最后输出每组的最后一行,得到每个ID的最终聚合结果。
结果验证
执行上述任意一种方法后,运行以下代码查看结果:
proc print data=finance_final noobs; run;
输出结果与需求目标一致:
| id | conc | borrowcap |
|---|---|---|
| 1 | level1 | high |
| 2 | level1 | high |
| 4 | level1 | |
| 5 | level1 | high |
内容的提问来源于stack exchange,提问作者T K
相关产品推荐
相关产品推荐

