如何使用SAS按指定规则对表数据按ID分组筛选保留目标行
SAS实现筛选逻辑方案
假设原数据集名为have,包含3个字段:id(用户ID)、grp(分组字段)、val(取值字段),可通过以下两种常用方法实现需求:
方法1:PROC SQL实现(逻辑清晰易读)
proc sql; create table want as select a.* from have a left join ( /* 先统计每个ID的唯一分组数量、对应最小取值 */ select id, count(distinct grp) as n_grp, min(val) as min_val from have group by id ) b on a.id = b.id where /* 规则1:同一ID对应多个分组时保留所有行 */ b.n_grp > 1 /* 规则2:同一ID仅1个分组时保留取值最小的行 */ or (b.n_grp = 1 and a.val = b.min_val); quit;
方法2:数据步双DoW循环实现(大数据量下效率更高)
data want; /* 第一轮遍历:统计当前ID的唯一分组数、单分组下的最小取值 */ n_grp = 0; min_val = 1e9; /* 初始值设为大于取值字段最大可能值即可 */ do until(last.id); set have; by id grp notsorted; /* 若数据集已提前按id、grp排序可去掉notsorted参数 */ if first.grp then n_grp + 1; if val < min_val then min_val = val; end; /* 第二轮遍历:按规则输出符合要求的行 */ do until(last.id); set have; by id; if n_grp > 1 then output; else if n_grp = 1 and val = min_val then output; end; drop n_grp min_val; run;
两种方案均完全覆盖需求规则:
- ID对应多个不同分组时,全量保留该ID所有行
- ID仅对应1个分组时,仅保留取值最小的行
- 匹配示例中ID 1201、1202、1203的预期处理结果
内容的提问来源于stack exchange,提问作者Chai
相关产品推荐
相关产品推荐

