変数名を取得する方法は沢山ありますが、知ってる方法すべてあげてみようと思います。
取得した変数名をマクロ変数に入れたい場合は
・変数値をマクロ変数に格納する方法「CALL SYMPUTX編」
・変数値をマクロ変数に格納する方法「SQL編」
などが参考になります。
data DT1; * サンプルデータ ;
label A="var1" B="var2" C="var3";
A=1; B="AAA"; C=100; output;
A=2; B="BBB"; C=200; output;
run;
*** ① CONTENTSプロシジャ ; proc contents data=DT1 out=VARS1 noprint; run; |
一番一般的なのが、この変数定義情報を取得できるCONTENTSプロシジャ。
*** ② SQLのDICTIONARYテーブル ; proc sql; create table VARS2 as select * from DICTIONARY.COLUMNS /* whereに"ライブラリ名"と"データセット名"を大文字で指定 */ where LIBNAME = "WORK" and MEMNAME = "DT1"; quit; |
- SQLプロシジャで参照することが出来るDICTIONARY.COLUMNS(全データセット, VIEWの変数定義情報が入ってる)を使う方法。
- DICTIONARYテーブルの詳細は「こちら」を参照。
*** ③ OPEN, ATTRN, VARNAME関数 ; data VARS3; length NAME $40.; DSID = open( "DT1" ); VARN = attrn( DSID, "NVARS" ); do i=1 to VARN; NAME = varname( DSID, i ); output; end; run; |
- まずOPEN関数でデータセットを開く。戻り値としてデータセット識別子というIDが返される。
- 次に ATTRN( データセット識別子, "NVARS" ) で変数の数を取得。
- 最後に変数の数だけループをまわして、VARNAME( データセット識別子, 変数の位置番号 ) で変数名を取得しています。
*** ④ CALL VNEXT ; data VARS4; length _NAME $40.; set DT1; do until ( _NAME="" ); call vnext( _NAME ); /* ^in の後のカッコの中は大文字で指定 */ if upcase( _NAME ) ^in ( "_NAME", "_ERROR_", "_N_", "" ) then output; end; keep _NAME; stop; run; |
- CALL VNEXTで変数名を取得。詳細は「こちら」を参照。
📝---------------
- プログラム中で作成している「_NAME」と同じ名前の変数がSETするデータセットにもあると正しく動かなくなるので、その時は上記プログラム中の「_NAME」を別の名前に変えて下さい。
*** ⑤ TRANSPOSE ; proc transpose data=DT1 (obs=0) out=VARS5; var _ALL_; run; |
海外のユーザー会で紹介された
「Atypical Applications of Proc Transpose(John King, Ouachita Clinical Data Services Inc., Hopper, AR)」
にある面白いテクニック。
transpose本来の使い方とは異なり、面白いアイディアです。
*** ⑥ ARRAY ; data VARS6; length _NAME $40. _ITER 8.; set DT1; array AR1(*) _numeric_; do _ITER = 1 to dim( AR1 ); _NAME = vname( AR1(_ITER) ); /* ^= の直後のテキストは大文字で指定 */ if upcase(_NAME) ^= "_ITER" then output; end; array AR2(*) _character_; do _ITER = 1 to dim( AR2 ); _NAME = vname( AR2(_ITER) ); /* ^= の直後のテキストは大文字で指定 */ if upcase(_NAME) ^= "_NAME" then output; end; keep _NAME; stop; run; |
- ARRAYで全数値変数と全文字変数を配列に割り当てて、VNAME関数で変数名を取得してます。
- VNAME関数は、変数名を文字として取得することができ、僕の頁「VNAME関数」で詳しく紹介されています。
📝---------------
- プログラム中で作成している「_NAME」「_ITER」と同じ名前の変数がSETするデータセットにもあると正しく動かなくなるので、その時は上記プログラム中の「_NAME」「_ITER」を別の名前に変えて下さい。
0 件のコメント:
コメントを投稿