2015年6月1日月曜日

DS2プロシジャ入門2:変数の宣言


今回は重要かつ細かい動きの解説になるので、間違いなどがあればご指摘お願いします。


変数の宣言

DS2プロシジャで変数を扱うには、まず変数の宣言が必要です。

変数を宣言する構文。
 dcl  データ型  変数名 ;

(データ型については別記事で解説予定なので、ここでは気にしないでください。)

例 **********;
proc ds2;
   data _DT1 (overwrite=yes);

       dcl char(10) VAR1;

       method run();
           dcl char(10) VAR2;
       end;
 
   enddata;
   run;
quit;

上の例では、長さ10の文字変数VAR1とVAR2を作成しています。

また変数を宣言する場所によって、その変数の役割も異なってきます。


ローカル変数

メソッドの中で宣言した変数は、そのメソッド内でしか使用できないうえ、
一時変数的な意味合いとなり、自動的に削除されます。

以下の例を見てください。
data DT1;
   do i=1 to 3;
       output;
   end;
run;

proc ds2;
  data DT2 (overwrite=yes) ;
    method run();
        dcl double A;
        set DT1;
        A + 1;
        put A;
    end;
  enddata;
run;
quit;

ログ
1
1
1

オブザベーションを読み込む度に「A+1」でどんどん足し合わせていこうとしてますが、
出力結果のログを見ると、全然足されてません。

これは、ローカル変数Aが一時的な変数のため、前回処理時の値を保持していないからです。
よってRETAINやSUMステートメントの機能も無効になります。


グローバル変数

メソッドの外で宣言した変数は、各メソッドから参照する事ができます。
(ローカル変数と違い、変数もちゃんと残ります)

ここで気をつける事あり。以下を見てください。
proc ds2;
  data DT1 (overwrite=yes) ;

    dcl double A;

    method init();
        A=1;
        put 'INITメソッドからPUT ・・・' A;
    end;
    method run();
        put 'RUNメソッドからPUT ・・・' A;
    end;
    method term();
        put 'TERMメソッドからPUT ・・・' A;
    end;
  enddata;
run;
quit;


ログ
 INITメソッドからPUT ・・・ 1
 RUNメソッドからPUT ・・・ 1
 TERMメソッドからPUT ・・・ .

やってる事
① まずグローバル変数Aを作ります。
② INITメソッド内で変数Aに値「1」を入れます。
③ そして各メソッドからAの値をログに出力してます。

ログを見ると、TERMメソッドの結果だけ欠損値になってる!


これは最後に実行されるTERMメソッドが、
処理を終了するんだから、まずグローバル変数達の値はリセットしておくね」、、となるからです。


(リセットされるグローバル変数は以下の場合を除く。)

・ SAS側があらかじめ定義している_N_などの変数
・ RETAINのような値を保持するようにしてる変数
・ パッケージ変数

という事で、TERMメソッドには気を付けましょう!


同名のグローバル変数とローカル変数を作った場合

proc ds2;
   data _DT1 (overwrite=yes);

       dcl char(10) VAR1;

       method init();
           dcl char(10) VAR1;
           VAR1 = 'aaa';
       end;
 
   enddata;
   run;
quit;


この場合INITメソッド内に書かれた 「VAR1 = 'aaa';」 は、INITメソッド内で宣言されたVAR1に対しての処理となります。



DS2プロシジャ入門記事

1: 基本構文
2: 変数の宣言

0 件のコメント:

コメントを投稿