私の現在のプロジェクトでは、さまざまな条件に基づいてマッチングを実装しなければならないことが何度かありました。最初に、問題のより詳細な説明。
テーブル テストを取得しました:
key Value
1 10
1 -10
1 10
1 20
1 -10
1 10
2 10
2 -10
ここで、ルールを適用して、グループ (キーの値で定義) 内で合計が 0 のペアを除外する必要があります。
期待される結果は次のようになります:
キー値
1 10
1 20
ソート順は関係ありません。
次のコードは、ソリューションの例です。my_id が 2 と 7 のオブザベーションを削除し、さらに 3 つのオブザベーションのうち 2 つを量 10 で削除します。
data test;
input my_id alias $ amount;
datalines4;
1 aaa 10
2 aaa -10
3 aaa 8000
4 aaa -16000
5 aaa 700
6 aaa 10
7 aaa -10
8 aaa 10
;;;;
run;
/* get all possible matches represented by pairs of my_id */
proc sql noprint;
create table zwischen_erg as
select a.my_id as a_id,
b.my_id as b_id
from test as a inner join
test as b on (a.alias=b.alias)
where a.amount=-b.amount;
quit;
/* select ids of matches to eliminate */
proc sort data=zwischen_erg ;
by a_id b_id;
run;
data zwischen_erg1;
set zwischen_erg;
by a_id;
if first.a_id then tmp_id1 = 0;
tmp_id1 +1;
run;
proc sort data=zwischen_erg;
by b_id a_id;
run;
data zwischen_erg2;
set zwischen_erg;
by b_id;
if first.b_id then tmp_id2 = 0;
tmp_id2 +1;
run;
proc sql;
create table delete_ids as
select zwischen_erg1.a_id as my_id
from zwischen_erg1 as erg1 left join
zwischen_erg2 as erg2 on
(erg1.a_id = erg2.a_id and
erg1.b_id = erg2.b_id)
where tmp_id1 = tmp_id2
;
quit;
/* use delete_ids as filter */
proc sql noprint;
create table erg as
select a.*
from test as a left join
delete_ids as b on (a.my_id = b.my_id)
where b.my_id=.;
quit;
アルゴリズムは機能しているようです。少なくとも、エラーの原因となった入力データは見つかりませんでした。しかし、なぜそれが機能するのか、誰も私に説明できませんでした。
それで、いくつか質問があります。
- このアルゴリズムは、入力データのすべての可能な組み合わせに対して正しい方法でペアを削除しますか?
- 正しく機能する場合、アルゴリズムはどのように詳細に機能しますか? 特に
tmp_id1 = tmp_id2 の部分。 - 対応するペアを削除するためのより良いアルゴリズムはありますか?
前もって感謝し、ハッピーコーディング
マイケル