部分的なサブストリングでSASハッシュルックアップを実行することは可能ですか?
したがって、ハッシュテーブルキーには「LongString」が含まれますが、ターゲットテーブルキーには「LongStr」が含まれます。
(ターゲットテーブルのキー文字列の長さは異なる場合があります)
できますが、きれいではなく、探しているパフォーマンス上の利点が得られない可能性があります。また、文字列の長さとテーブルのサイズによっては、すべてのハッシュテーブル要素をメモリに収めることができない場合があります。
秘訣は、最初に可能なすべてのサブストリングを生成し、次にハッシュテーブルで「multidata」オプションを使用することです。
照合する単語を含むデータセットを作成します。
data keys;
length key $10 value $1;
input key;
cards;
LongString
LongOther
;
run;
可能なすべての部分文字列を生成します。
data abbreviations;
length abbrev $10;
set keys;
do cnt=1 to length(key);
abbrev = substr(key,1,cnt);
output;
end;
run;
検索する用語を含むデータセットを作成します。
data match_attempts;
length abbrev $10;
input abbrev ;
cards;
L
Long
LongO
LongSt
LongOther
;
run;
ルックアップを実行します。
data match;
length abbrev key $10;
set match_attempts;
if _n_ = 1 then do;
declare hash h1(dataset:'abbreviations', multidata: 'y');
h1.defineKey('abbrev');
h1.defineData('abbrev', 'key');
h1.defineDone();
call missing(abbrev, key);
end;
if h1.find() eq 0 then do;
output;
h1.has_next(result: r);
do while(r ne 0);
h1.find_next();
output;
h1.has_next(result: r);
end;
end;
drop r;
run;
出力(「Long」が2つの一致を返す方法に注意してください):
Obs abbrev key
=== ========= ==========
1 Long LongString
2 Long LongOther
3 LongO LongOther
4 LongSt LongString
5 LongOther LongOther
さらにいくつかのメモ。ハッシュテーブルが演算子のようなものをサポートしない理由は、ハッシュテーブルにlike
レコードを挿入する前にキーを「ハッシュ」するためです。ルックアップが実行されると、ルックアップする値は「ハッシュ」され、ハッシュされた値に対して一致が実行されます。値がハッシュされると、値のわずかな変更でもまったく異なる結果が得られます。以下の例を見てください。2つのほぼ同一の文字列をハッシュすると、2つの完全に異なる値が生成されます。
data _null_;
length hashed_value $16;
hashed_value = md5("String");
put hashed_value= hex32.;
hashed_value = md5("String1");
put hashed_value= hex32.;
run;
出力:
hashed_value=27118326006D3829667A400AD23D5D98
hashed_value=0EAB2ADFFF8C9A250BBE72D5BEA16E29
このため、ハッシュテーブルはlike
演算子を使用できません。
最後に、いくつかのサンプルデータを提供してくれた@vasjaに感謝します。
Iteratorオブジェクトを使用してキーをループし、自分でマッチングを行う必要があります。
data keys;
length key $10 value $1;
input key value;
cards;
LongString A
LongOther B
;
run;
proc sort data=keys;
by key;
run;
data data;
length short_key $10;
input short_key ;
cards;
LongStr
LongSt
LongOther
LongOth
LongOt
LongO
LongSt
LongOther
;
run;
data match;
set data;
length key $20 outvalue value $1;
drop key value rc;
if _N_ = 1 then do;
call missing(key, value);
declare hash h1(dataset:"work.keys", ordered: 'yes');
declare hiter iter ('h1');
h1.defineKey('key');
h1.defineData('key', 'value');
h1.defineDone();
end;
rc = iter.first();/* reset to beginning */
do while (rc = 0);/* loop through the long keys and find a match */
if index(key, trim(short_key)) > 0 then do;
outvalue = value;
iter.last(); /* leave after match */
end;
rc = iter.next();
end;
run;