首页 > 解决方案 > SAS - 选择第一次出现唯一 ID 的行(ID 可以在两列中)

问题描述

客户(ID_a 和 ID_b)之间的计算距离(var1)。Var2 和 var3 包含一些其他变量。数据按 ID_a 和 var1 排序(因此最接近的距离排在第一位)。

data have;
input (ID_a ID_b var1 var2 var3)($);
cards;
    A B 12 xxx yyy
    A C 36 xxx yyy
    C D 17 xxx yyy
    D A 18 xxx yyy
    D F 80 xxx yyy
    G B 20 xxx yyy
    G K 32 xxx yyy

run;

现在我保留第一次出现 ID 的行无论是在 ID_a 列还是 ID_b 列。输出应如下所示:

data want;
input (ID_a ID_b var1 var2 var3)($);
cards;
   A B 12 xxx yyy
   C D 17 xxx yyy
   G K 32 xxx yyy

run;

目标是获得一个列表,其中每个客户与一 (1) 个其他客户配对,并且距离尽可能近。当然有多种可能的组合,因为 A 可以最接近 B,同时 C 也可以最接近(甚至更接近)B。如果可能的话,最好得到最低的组合总距离。否则按 ID_a 的升序遍历组合

这样做的最佳解决方案是什么?我一直在用 NODUPKEY 检查 PROC SORT,但这不是解决方案,因为每一行都是唯一的组合。

我正在考虑使用宏来选择每个 ID_a 的第一行,如果 ID 已经在 ID_a 或 ID_b 中使用过,则继续到 ID_a 的第二行。但是我找不到这样的代码的任何示例,我不确定这是最好的解决方案。因此,任何有关解决方案或代码的建议都会很好。谢谢!

标签: sas

解决方案


根据评论,我建议按距离对数据进行排序,并选择出现包含唯一对项的第一对。

例子:

Ahash对于跟踪所选项目非常有效。

proc sort data=have;
  by var1 id_a;

data want;
  length id $8;
  if _n_ = 1 then do;
    declare hash items();
    items.defineKey('id');
    items.defineDone();
    call missing(id);
  end;

  set have;
   
  if items.check(key:id_a) ne 0 and items.check(key:id_b) ne 0 then do;
    output;
    items.add(key:id_a, data:id_a);
    items.add(key:id_b, data:id_b);
  end;

  drop id;
run;

推荐阅读