2014年8月5日火曜日

SETステートメントの落とし穴1「値の保持」


今回はわかりやすいように2回くらいに分けて紹介したいと思います。

サンプルデータ

data DT1;
   A="001"; B=1; C=.; output;
   A="002"; B=.; C=.; output;
   A="003"; B=1; C=.; output;
run;

data DT2;
   A="004"; B=.; output;
   A="005"; B=1; output;
   A="006"; B=.; output;
run;

proc sort data=DT1; by A; run;
proc sort data=DT2; by A; run;

 DT1DT2
 C  
 001 
  1  
  .  
 002
  . 
  .  
 003
  1 
  .  
 A  
 B  
 004 
  .  
 005
  1 
 006
  .


問題
サンプルデータより以下のプログラムを実行すると、①②どちらのデータが出来るでしょうか?

data DT3;
   set DT1 DT2;
   if  B=1 then C=111;
run;

 ①
  A  
C
  001 
  1   
 111 
  002
  . 
  .   
  003
  1 
 111 
  004
  .
  .
  005
  1
 111
  006
  .
  .
  A  
C
  001 
  1   
 111 
  002
  . 
  .   
  003
  1 
 111
  004
  .
  .
  005
  1
 111
  006
  .
 111

正解は②です!


解説

はじめに、内部処理の説明は経験に基づくもので独自解釈になってる可能性もあるので、あしからず。。

内部ではまず、
プログラムデータベクトル(PDV)という入れ物に、データを1行ずつ放り込んで処理してから、結果のデータセットDT3に出力しています。

以下、処理の流れ。

























赤字にした 6) と 10) が重要なポイントです。

・読み込むデータセットが変わった場合、PDV内の変数値が初期化される。
・PDV内の変数が、読み込むデータセットにない場合、前の値が保持される。



もし①のような結果が欲しい場合は、以下のようにDT1,DT2双方にない新たな変数名に変えてあげればok。
data DT3;
   set DT1 DT2 ;
   if  B=1 then D=111;
run;

(新たな変数は、次の行を読みにいく度に毎回初期化される性質を持ってるので上記であげた「値の保持」という影響をうけません。)


次回に続く。。


0 件のコメント:

コメントを投稿