SASを覚えはじめたという方から、この質問を頂くことが多いので解説したいと思います。
(最後に注意点の記事リンクも貼ったので、そちらも要参照)
* サンプルデータ ;
data DT1;
input A$ B$ @@;
cards;
001 AA 002 BB 003 CC
;
上記の変数A,Bの値をマクロ変数に格納してみましょう。
上記青字部分の解説
処理の流れ
* サンプルデータ ;
data DT1;
input A$ B$ @@;
cards;
001 AA 002 BB 003 CC
;
A
|
B
|
---|---|
001
|
AA
|
002
|
BB
|
003
|
CC
|
上記の変数A,Bの値をマクロ変数に格納してみましょう。
* 変数値をマクロ変数に格納 ;
data _null_; set DT1 end=_EOF; if _EOF then call symputx("OBS", _N_); call symputx( cats("A",_N_) , A ); call symputx( cats("B",_N_) , B ); run; * ログにマクロ変数値を展開 ; %macro MAC; %do i=1 %to &OBS; %put &&A&i &&B&i; %end; %mend; %MAC;
ログ
001 AA
002 BB
003 CC
|
上記青字部分の解説
end = 一時変数名
| 最後のオブザベーションを読み込んだ時、一時変数に「1」が入る。 一時変数名は任意の名前でOK
|
call symputx
| 構文・・・call symputx("マクロ変数名", 格納したい値 )
値をマクロ変数に格納する。 |
_N_
| SASの自動変数で、データステップの反復回数が格納されている。 つまり、読み込んだオブザベーションに対して、1~連番をふったような値が入る。
|
cats関数
| 構文・・・cats(値1, 値2 … )
値の両端の半角スペースを取り除いて結合する。 |
%doループ
| %do マクロ変数名 = 開始値 %to 終了値;
%end; マクロ変数の値を開始値から終了値まで変化させながら、ループさせる。 |
処理の流れ
data _null_;
set DT1 end=_EOF; if _EOF then call symputx("OBS", _N_); 最後のオブザベーションを読み込んだ時に、_N_の値をマクロ変数OBSに格納している。 (つまりオブザベーション数をマクロ変数に格納) call symputx( cats("A",_N_) , A ); call symputx( cats("B",_N_) , B ); run; 変数Aについて 1オブザベーション目の値をマクロ変数A1に 2オブザベーション目の値をマクロ変数A2に ・・・と次々マクロ変数に格納していく。変数Bも同様。 %do i=1 %to &OBS;
%put &&A&i &&B&i;
%end; %mend;
%MAC;
%DOでマクロ変数 i の値を1,2,3…と変化させながら、オブザベーションの数だけループさせる。
|
📝注意点
「CALL SYMPUTX」で数値をマクロ変数に格納すると丸められる場合があるので注意
今回のテクニックの中で使用している「_N_」と「END=オプション」は「サブセット化IF」と一緒に使用すると正しく動かなくなる事があります。
(解説記事:「サブセット化IFでありがちな落とし穴」)
(解説記事:「サブセット化IFでありがちな落とし穴」)
0 件のコメント:
コメントを投稿