2017-02-23 35 views
1

私はhttp://www.sascommunity.org/mwiki/images/2/22/Hashmerge.sasし、次の例のデータセットで発見%HASHMERGEマクロを使用しています:workingデータセットでSASハッシュマージ - ハッシュオブジェクトとして小さいデータセット

data working; 
    length IID TYPE $12; 
    input IID $ TYPE $; 
    datalines; 
    B 0 
    B 0 
    A 1 
    A 1 
    A 1 
    C 2 
    D 3 
    ; 
run; 

data master; 
    length IID FIRST_NAME MIDDLE_NAME LAST_NAME SUFFIX_NAME $12; 
    input IID $ FIRST_NAME $ MIDDLE_NAME $ LAST_NAME $ SUFFIX_NAME; 
    datalines; 
    X John James Smith Sr 
    Z Sarah Marie Jones . 
    Y Tim William Miller Jr 
    C Nancy Lynn Brown . 
    B Carol Elizabeth Collins  . 
    A Wayne Mark Rooney . 
    ; 
run; 

、私は_NAME変数を添付しようとしていますこのハッシュマージを使用してmasterデータセットから取得します。出力はうまく見え、望ましい出力です。しかし、私の実際のシナリオでmasterデータセットは大きすぎて、ハッシュオブジェクトに収まらず、マクロはハッシュオブジェクトとして配置し続けます。私は最終的にworkingデータセットがハッシュオブジェクトであるところにこれらの2つのデータセットを反転したいと思いますが、コードを反転すると希望の出力を得ることができません。以下に調整し所望の出力やニーズを生成するマクロの一部ですが、私はこれを設定する方法がわからない午前:

出力希望
data OUTPUT; 
    if 0 then set MASTER (keep=IID FIRST_NAME MIDDLE_NAME LAST_NAME SUFFIX_NAME) 
    WORKING (keep=IID); 
    declare hash h_merge(dataset:"MASTER"); /* I want WORKING to be the hash object since it's smaller! */ 
    rc=h_merge.DefineKey("IID"); 
    rc=h_merge.DefineData("FIRST_NAME","MIDDLE_NAME","LAST_NAME","SUFFIX_NAME"); 
    rc=h_merge.DefineDone(); 
    do while(not eof); 
     set WORKING (keep=IID) end=eof; 
     call missing(FIRST_NAME,MIDDLE_NAME,LAST_NAME,SUFFIX_NAME); 
     rc=h_merge.find(); 
     output; 
     end; 
    drop rc; 
    stop; 
run; 

:それは何をあなたを行うには可能だが

IID FIRST_NAME MIDDLE_NAME LAST_NAME SUFFIX_NAME 
--------------------------------------------------- 
B Carol  Elizabeth Collins  
B Carol  Elizabeth Collins  
A Wayne  Mark   Rooney 
A Wayne  Mark   Rooney 
A Wayne  Mark   Rooney 
C Nancy  Lynn   Brown 
D     
+0

作業データセットのIIDを使用してマスタデータセットをフィルタ処理した後、フィルタリングされたマスターデータセットを作業データセットとマージすると、両方のデータセットが小さく、扱いやすくなります。 –

+0

私は 'SQL left join'フィルタを試しました。マスターデータセットの読み込み、並べ替え、' if a 'を使って 'working(in = a)master'をマージするよりも時間がかかりました。 – Foxer

+0

これをフィルタリングしてみてください:proc sql; IIDが作業中のIIDを選択する(keep = keep = IID FIRST_NAME MIDDLE_NAME LAST_NAME SUFFIX_NAME)からselect *としてテーブルNew_masterを作成します。終了する; –

答えて

0

例えば、私はあなたが非目的のマクロからそれを得るのではないかと思う。これは通常の方法ではないからです。通常、メインデータセットをそのフォームに保持し、リレーショナルデータセットをハッシュテーブルに入れたいとします。通常、サイズは逆になっています。リレーショナルテーブルは通常、メインテーブルよりも小さくなります。

個人的に私はこの特定のケースではハッシュを使用しません。私はフォーマット(または3つ)を使用します。ハッシュと同じくらい速く、サイズの問題が少ない(メモリに収まる必要がないため)、サイズのために最終的には速度が落ちる(しかし、壊れない!)。

フォーマットソリューション:

言っ
data working; 
    length IID TYPE $12; 
    input IID $ TYPE $; 
    datalines; 
    B 0 
    B 0 
    A 1 
    A 1 
    A 1 
    C 2 
    D 3 
    ; 
run; 

data master; 
    length IID FIRST_NAME MIDDLE_NAME LAST_NAME SUFFIX_NAME $12; 
    input IID $ FIRST_NAME $ MIDDLE_NAME $ LAST_NAME $ SUFFIX_NAME; 
    datalines; 
    X John James Smith Sr 
    Z Sarah Marie Jones . 
    Y Tim William Miller Jr 
    C Nancy Lynn Brown . 
    B Carol Elizabeth Collins  . 
    A Wayne Mark Rooney . 
    ; 
run; 

data for_fmt; 
    set master; 
    retain type 'char'; 
    length fmtname $32 
     label $255 
     start $255 
     ; 
    start=iid; 

    *first; 
    label=first_name; 
    fmtname='$FIRSTNAMEF'; 
    output; 

    *last; 
    label=last_name; 
    fmtname='$LASTNAMEF'; 
    output; 

    *middle; 
    label=middle_name; 
    fmtname='$MIDNAMEF'; 
    output; 

    *suffix; 
    label=suffix_name; 
    fmtname='$SUFFNAMEF'; 
    output; 

    if _n_=1 then do; 
    start=' '; 
    label=' '; 
    hlo='o'; 
    fmtname='$FIRSTNAMEF'; 
    output; 
    fmtname='$LASTNAMEF'; 
    output; 
    fmtname='$MIDNAMEF'; 
    output; 
    fmtname='$SUFFNAMEF'; 
    output; 
    end; 
run; 

proc sort data=for_fmt; 
    by fmtname start; 
run; 

proc format cntlin=for_fmt; 
quit; 

data want; 
    set working; 
    first_name = put(iid,$FIRSTNAMEF.); 
    last_name = put(iid,$LASTNAMEF.); 
    middle_name = put(iid,$MIDNAMEF.); 
    suffix_name = put(iid,$SUFFNAMEF.); 

run; 

...

あなたはハッシュテーブルでこれを行うにはしたくない場合は、何があるMASTERに行ごとに、行う必要があると思います、作業表でFINDを実行し、成功した場合はREPLACE、失敗した場合はFIND_NEXTおよびREPLACEを実行します。

問題がありますか?あなたは少なくとも1つのマスターの行、を探しているあなた自身が非常に大きいと指摘した。 WORKINGが100kで、MASTERが100Mの場合は、一致ごとに1000回の検索が行われます。これは非常に高価で、おそらくあなたが他のソリューションを使っているほうが良いということです。

+0

いつものようにすばらしいアドバイスをいただき、ありがとうございます。私のシナリオでは、ハッシュテーブルを使用したドキュメントがあまりないので理にかなっています。私はフォーマットメソッドを与えるだろう! 'WORKING'は22MMの行を持ち、' ​​MASTER'は350MMの行を持っています - 厄介なものですが、完了しなければなりません。 – Foxer

+0

私は間違いなくハッシュでそれをしないだろう - 別の解決策を見つける。たぶんMASTERをいくつかのセットに分割し、それらをハッシュします。あなたはハッシュにどの程度のサイズを収めることができますか?どのくらいの記憶がありますか?より多くのメモリやより小さいデータセットを取得する - たとえば、100MMをハッシュに収めることができれば、4つのハッシュで十分です。特に、インテリジェントに分割することができれば(インデックスなど)、WORKINGから5MMのロー毎回22/100ではなく、100MMの行を正確に修正してください)。 – Joe

関連する問題