PAYATHON 2026

SAS 如何按 ID 汇总条件并生成多个标记变量?

数据小许

结论

先按 ID 汇总每条记录是否符合对应条件,再将汇总结果合并回原数据。如果每个 ID 只需显示一行标记,可以只给输出中的 first.ID 赋值。

示例中的期望结果与“每个 ID 只标记一次”并不完全一致:ID 001 的 Flag1 有两条记录标为 Y;Flag2 标在 G5="Y" 的记录上,而不是该 ID 的首条记录上。另外,按文字描述,Relation 为 PossiblyRelated 的记录也应满足 Flag1 条件,但期望结果将该行标为 N。下面的代码按文字描述中的规则处理,请根据实际业务规则调整。

按 ID 汇总,只在首条记录显示

PROC SQL 中的 GROUP BY ID 可以计算每个 ID 的汇总值。用 MAX 汇总 0/1 条件标记时,只要组内有一条记录符合条件,结果就是 1。

proc sql;
  create table id_flags as
  select ID,
         max(Relation in ("Related", "PossiblyRelated")) as Flag1_num,
         max(G5 = "Y") as Flag2_num
  from mydataset
  group by ID;
quit;

proc sort data=mydataset;
  by ID;
run;

proc sort data=id_flags;
  by ID;
run;

data desired;
  merge mydataset(in=in_data) id_flags;
  by ID;
  if in_data;

  length Flag1 Flag2 $1;
  if first.ID then do;
    Flag1 = ifc(Flag1_num, "Y", "N");
    Flag2 = ifc(Flag2_num, "Y", "N");
  end;
  else do;
    Flag1 = "N";
    Flag2 = "N";
  end;

  drop Flag1_num Flag2_num;
run;

这里的 Flag1 和 Flag2 表示整个 ID 组是否曾满足对应规则,并且只显示在按 ID 排序后的首条记录上。其他记录设为 N。如果希望其他行留空,可以把 else 分支改为:

else call missing(Flag1, Flag2);

first.ID 是 SAS BY-group 处理中自动生成的临时变量。使用前,数据必须按 ID 排序。同一 ID 有多条记录时,哪条记录算首条取决于排序后的顺序。

如果要标记首条符合条件的记录

如果需求是每个 ID 只在“第一条符合条件的记录”上标记 Y,而不是把 ID 的汇总结果放在首条记录上,可以用 BY-group 处理和保留状态:

data desired_first_match;
  set mydataset;
  by ID;

  length Flag1 Flag2 $1;
  retain found1 found2;

  if first.ID then do;
    found1 = 0;
    found2 = 0;
  end;

  Flag1 = "N";
  Flag2 = "N";

  if not found1 and Relation in ("Related", "PossiblyRelated") then do;
    Flag1 = "Y";
    found1 = 1;
  end;

  if not found2 and G5 = "Y" then do;
    Flag2 = "Y";
    found2 = 1;
  end;

drop found1 found2;
run;

这段代码会分别标记每个 ID 中首次符合 Flag1 和 Flag2 条件的记录。数据需要先按 ID 排序。如果要按日期或其他字段确定“首次”,应先按 ID 和该字段排序。

扩展到更多规则

每条规则都可以先转换为 0/1,再按 ID 使用 MAX 汇总。例如,新增一个条件为 Type="A" 的 Flag3:

max(Type = "A") as Flag3_num

数据量较大或规则较多时,集中计算汇总标记再合并回原表,通常更容易维护。需要区分的是“每个 ID 是否满足条件”和“哪条记录满足条件”:前者是组级汇总,后者需要确定要标记哪条记录。

备注:内容仅供参考。