2015年7月7日火曜日

ARRAYステートメントにRETAIN機能を付与する小技




今回は「RETAIN」と「ARRAY」まわりの話になります(この2つよく分からんって方は以下記事を参照)



では本題。以下のようなデータがあったとします。

* サンプルデータ ;
data DT1;
input A B;
cards;
1 10
. .
2 .
. 20
. .
;

 A  
 B  
 1 
 10 
 . 
 . 
 2
 . 
 . 
 20 
 . 
 . 


変数A, Bについて、欠損値であれば前のオブザベーションからRETAINで値をひっぱってきたいとします。↓
(引っ張った結果をそれぞれ変数A2, B2とする。)

 A  
 B 
 A2  
 B2  
 1 
 10 
 1 
 10 
 . 
 . 
 1 
 10 
 2 
 . 
 2
 10 
 . 
 20 
 2
 20 
 . 
 . 
 2
 20 


そこで最初に思いつくのが、以下のように ARRAY と RETAIN を組み合わせる方法。

data DT2;
   set DT1;

   retain A2 B2;

   array AR1(*) A B;
   array AR2(*) A2 B2;

   do i=1 to dim(AR1);
       if AR1(i) ^=. then AR2(i) = AR1(i);
   end;
   drop i;
run;


実はこれ、RETAINを使わなくてもいけちゃいます。
最近マニュアルを読み返して知ったんですが、ARRAYで初期値を与えるとRETAIN機能が付与されるみたいです。

初期値を与える
data DT2;
   set DT1;

   array AR1(*) A B ;
   array AR2(*) A2 B2 ( 2*. ) ;

   do i=1 to dim(AR1);
        if AR1(i) ^=. then AR2(i) = AR1(i);
   end;
   drop i;
run;


 A  
 B 
 A2  
 B2  
 1 
 10 
 1 
 10 
 . 
 . 
 1 
 10 
 2 
 . 
 2
 10 
 . 
 20 
 2
 20 
 . 
 . 
 2
 20 

プログラム青字部分のようにカッコの中に初期値を与えることが出来て、たとえば、
「array AR(*) A B C  ( 10 20 30 );」 と書けば、「A=10 B=20 C=30」 と初期値が与えられます。
「array AR(*) A B C  ( 3*. );」 と書けば、「A=. B=. C=.」 と3つまとめて初期値として欠損値を与えることが出来ます。


ただし!
※ 初期値を与えてRETAIN機能が付与されるのは、RETAINステートメントと同様にデータステップ内で新たに作成した変数のみです。


0 件のコメント:

コメントを投稿