2014年3月14日金曜日

変数名を取得する「CALL VNEXT」。




以下は、CALL VNEXTを使って変数定義をデータセットに書き出す例です。


* サンプルデータ作成 ;
data DT1;
input A1 A2 A3;
cards;
1 1 2
2 1 2
3 1 2
;

* 変数定義をデータセットに書き出す ;
data DT2;

   length  _NAME  $40. _TYPE  $1.;   * ① ;
   set DT1;

   do until ( _NAME="" );  * ② ;
       call vnext( _NAME, _TYPE, _LENGTH ); * ③ ;
       if  _NAME ^=""  then  output;
   end;

   stop;  * ④ ;
   keep _NAME _TYPE _LENGTH ;

 run;

結果データ「DT2」



解説

①変数定義を放り込む変数に、LENGTHを指定。

②CALL VNEXTは実行する度に、順に変数定義を読みに行きます。
なので読み込む定義がなくなるまでDO UNTILでループします。

③変数名を「_NAME」、型を「_TYPE」、変数長を「_LENGTH」という変数に放り込むよう指定。
もし変数名だけ取得したい場合、「call vnext( _NAME)」としてもOK。

④変数定義を取得した後はDT1を読み込み続ける必要がないので、STOPステートメントでデータステップを停止。


POINT
  • 「_ERROR_」「_N_」などの自動変数の定義も読み込まれます。
  • プログラム中で作成した変数(今回の例では「_NAME」「_TYPE」「_LENGTH」)の定義も読み込まれます。またこれらと同じ名前の変数がSETで読み込んだデータセットにもある場合は正しく動かなくなるので、その時はプログラム中で作成する変数名を変える必要あり。
  • 型は文字変数であれば"C"、数値変数であれば"N"が入ります。
  • 得られる変数名の順番は、バージョンや環境によって異なる可能性があるので当てにしない方が良い。




応用例

全変数一括で何か処理したい場合、「CALL VNEXT」と「CALL EXECUTE」を組み合わせると便利です。

CALL EXECUTEはデータステップ100万回の以下記事にて分かり易く解説されてるので参照下さい。
http://sas-tumesas.blogspot.jp/2013/11/call-execute.html


*** 全変数を一括でRENAME(先頭に"X"を付与)するサンプル ;
data _NULL_;

    length _NAME $40.;
   set DT1 ( keep= drop= ) ;   * ① ***;

   call execute( "DATA DT3; SET DT1; RENAME " );

   do until ( _NAME="" );
      call vnext( _NAME );

      /* ^in の後のカッコの中は大文字で指定 */
      if upcase( _NAME ) ^in ( "_NAME", "_ERROR_", "_N_", "" ) then
         call execute( _NAME || "=X" || _NAME );  * ② ***;
   end;

   call execute( "; RUN;" );
   stop;

 run;

「CALL EXECUTE」で生成されるプログラム
 DATA DT3; SET DT1; RENAME
 A1                                      =XA1
 A2                                      =XA2
 A3                                      =XA3
 ; RUN;

結果データセット「DT3」


📝
プログラム中で作成している「_NAME」と同じ名前の変数が①の部分でSETしたデータセットにもある場合は正しく動かなくなるので、その時はプログラム中の「_NAME」を別の名前に変える必要がある。



解説

基本的に最初のサンプルプログラムをもとに発展させたやり方です。

①RENAMEする変数を選択したい場合は、3行目の「SET DT1 (keep= drop=)」のところで、
 set DT1 ( keep=A2 A3  drop= );


としたり、RENAMEしたくない変数がある場合、
 set DT1 ( keep=  drop=A1 );

のようにすればOK。

上2つのように書くと、以下のプログラムが生成されます。
 DATA DT3; SET DT1; RENAME
 A2                                      =XA2
 A3                                      =XA3
 ; RUN;


自動変数等がRENAME対象に入らないよう除外した上で、CALL EXECUTEでRENAME処理の文を生成しています。
SASのバージョンが上がって、もし自動変数が追加されてたら、ここをちょっと変える必要あり。



工夫すればなんでも出来るので非常に使い勝手がいいです。
変数を取得する方法は他にも沢山あり、「変数名を取得する方法 [まとめ]」でまとめてるので参考までに。



0 件のコメント:

コメントを投稿