BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
sasone
Quartz | Level 8

いつもお世話になっております。

以下のようなデータセットA,Bがあり、それらを単純にマージしてCに
するという動きをHashで代替できないかと考えております。

data A;
  USUBJID="01";output;
  USUBJID="02";output;
run;
data B;
  USUBJID="01";AESEQ=1;output;
  USUBJID="01";AESEQ=2;output;
run;
data C;
  merge A B;
  by USUBJID;
run;

ですが以下のように書いても上手くCが再現されません。そもそもHashでは
フルマージはできないのでしょうか。
ご教示のほどよろしくお願い申し上げます。

 

data C;
  if 0 then set B;
  if 1 then do;
    declare hash ae(dataset:"B");
      ae.definekey("USUBJID");
      ae.definedata("AESEQ");
      ae.definedone();
  end;
  do until(eof);
    set A end=eof;
      if ae.find()=0 then output;
      else do;
        call missing(AESEQ);
      output;
      end;
  end;
  stop;
run;
1 ACCEPTED SOLUTION

Accepted Solutions
amatsu
Obsidian | Level 7

 

こんにちは。

 

Hashオブジェクトはマージと挙動が異なるんで、以下の前提条件が成立していると仮定します。

 

・SASのバージョンは9.3以上(9.3未満だと今回のプログラムは動作しません)

・AにはUSUBJIDの重複はない。

・BのUSUBJIDは、Aにもすべて存在する。

 

 

 

data C;
  if 0 then set B;
  if _n_=1 then do;
    declare hash ae(dataset:"B", multidata:'y');
      ae.definekey("USUBJID");
      ae.definedata("AESEQ");
      ae.definedone();
  end;
  set A;
  
  rc = ae.find();
  if rc ^= 0 then do;
    call missing(AESEQ);
  	output;
  end;
  
  do while (rc = 0);
    output;
    rc = ae.find_next();
  end;

run;

 

 

 

 

View solution in original post

2 REPLIES 2
amatsu
Obsidian | Level 7

 

こんにちは。

 

Hashオブジェクトはマージと挙動が異なるんで、以下の前提条件が成立していると仮定します。

 

・SASのバージョンは9.3以上(9.3未満だと今回のプログラムは動作しません)

・AにはUSUBJIDの重複はない。

・BのUSUBJIDは、Aにもすべて存在する。

 

 

 

data C;
  if 0 then set B;
  if _n_=1 then do;
    declare hash ae(dataset:"B", multidata:'y');
      ae.definekey("USUBJID");
      ae.definedata("AESEQ");
      ae.definedone();
  end;
  set A;
  
  rc = ae.find();
  if rc ^= 0 then do;
    call missing(AESEQ);
  	output;
  end;
  
  do while (rc = 0);
    output;
    rc = ae.find_next();
  end;

run;

 

 

 

 

sasone
Quartz | Level 8

amatsuさま

 

早速のご回答、誠に有難うございます。
フルマージというよりもLEFT OUTER JOINに近い挙動ですが、
これで私の抱えている問題が十分解決できました。
本当に有難うございました!

 

(ただし、手持ちの比較的レコード数の多いデータセットB(35000obs)とA(55obs)でHashによる結合(definekey4つ)を
試したところ、「ERROR: メモリ不足のため、このステップの処理を中止しました。」が出て実行できませんでした。

Bを30000obsに落とすと動きます。大規模データにはHashは使えないのかも知れません。)