1

部分的なサブストリングでSASハッシュルックアップを実行することは可能ですか?

したがって、ハッシュテーブルキーには「LongString」が含まれますが、ターゲットテーブルキーには「LongStr」が含まれます。

(ターゲットテーブルのキー文字列の長さは異なる場合があります)

4

2 に答える 2

2

できますが、きれいではなく、探しているパフォーマンス上の利点が得られない可能性があります。また、文字列の長さとテーブルのサイズによっては、すべてのハッシュテーブル要素をメモリに収めることができない場合があります。

秘訣は、最初に可能なすべてのサブストリングを生成し、次にハッシュテーブルで「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に感謝します。

于 2012-09-10T14:04:07.547 に答える
1

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;
于 2012-09-10T13:18:21.740 に答える