You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SAS实现基于a、b字段关联的分组算法?

当然可以实现!你说的这种分组逻辑本质上是图论里的连通分量问题——把每一行当成一个节点,只要两行的a或b值相同,就给这两个节点连一条边,最终同一个连通分量里的所有节点就归为同一个分组。下面是用SAS实现的具体方案:

首先先把你的示例数据整理成清晰的表格:

#nab预期分组
1111
2121
3221
4231
5342
6352
7452

实现思路:并查集(Union-Find)算法

这是处理连通分量问题最高效的算法之一,核心是记录每个元素的父节点,通过合并操作把关联的元素归到同一组,最终找到每个元素的根节点作为分组ID。

下面是完整的SAS代码:

/* 第一步:准备原始数据 */
data have;
  input #n a b;
  datalines;
1 1 1
2 1 2
3 2 2
4 2 3
5 3 4
6 3 5
7 4 5
;
run;

/* 第二步:用并查集算法计算分组 */
data want;
  set have;
  retain group_id 0;
  length key $20 root $20;
  
  /* 初始化哈希表,存储每个a/b值对应的根节点,以及分组的父节点映射 */
  if _n_ = 1 then do;
    declare hash uf(ordered:'no');
    uf.defineKey('key');
    uf.defineData('root');
    uf.defineDone();
  end;

  /* 处理当前行的a值:如果a未记录过,新建分组 */
  key = cats('a_', a);
  if uf.find() ne 0 then do;
    group_id + 1;
    root = cats('g_', group_id);
    uf.add();
  end;
  a_root = root;

  /* 处理当前行的b值:如果b未记录过,新建分组 */
  key = cats('b_', b);
  if uf.find() ne 0 then do;
    root = cats('g_', group_id);
    uf.add();
  end;
  b_root = root;

  /* 合并a和b对应的分组(如果它们属于不同分组) */
  if a_root ne b_root then do;
    /* 找到a_root的最终根节点 */
    temp = a_root;
    do while (uf.find(key:temp) eq 0);
      temp = root;
    end;
    final_a_root = temp;

    /* 找到b_root的最终根节点 */
    temp = b_root;
    do while (uf.find(key:temp) eq 0);
      temp = root;
    end;
    final_b_root = temp;

    /* 合并两个分组:让其中一个根指向另一个 */
    if final_a_root ne final_b_root then do;
      key = final_b_root;
      root = final_a_root;
      uf.add();
    end;
  end;

  /* 确定当前行的最终分组ID */
  temp = a_root;
  do while (uf.find(key:temp) eq 0);
    temp = root;
  end;
  group = input(scan(temp, 2, '_'), best.);

  /* 清理临时变量 */
  drop key root a_root b_root temp final_a_root final_b_root;
run;

/* 查看结果 */
proc print data=want;
run;

代码说明:

  1. 我们用哈希表uf来存储两种映射:
    • a_xxx/b_xxx:记录每个a、b值对应的初始分组根节点
    • g_xxx:记录分组之间的合并关系(比如g_2指向g_1表示分组2合并到分组1)
  2. 对每一行,先处理a和b值,为未出现过的值创建新分组;
  3. 如果当前行的a和b属于不同分组,就合并这两个分组;
  4. 最后通过追溯根节点,得到当前行的最终分组ID。

运行这段代码后,输出的group列会和你预期的分组完全一致。

内容的提问来源于stack exchange,提问作者fossekall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:33:03