ラベル プロシジャ: CONTENTS の投稿を表示しています。 すべての投稿を表示
ラベル プロシジャ: CONTENTS の投稿を表示しています。 すべての投稿を表示

2019年4月11日木曜日

データセットと変数の定義(属性)を表示する【CONTENTSプロシジャ】




CONTENTSプロシジャで、データセットと変数の定義情報を表示することが出来ます。




例① データセットと変数の定義情報を表示する

proc contents data=sashelp.class varnum;
run;


結果ビューア


  • データセットと変数の定義情報が結果ビューアに表示されます
  • 「data=」に対象のデータセットを指定
  • 「varnum」を指定すると、変数定義(上の出力イメージの一番最後の表)に表示する変数名をデータセットに定義されている順番に表示します(デフォルトだと定義順にならない)




例② 定義をデータセットに出力する

proc contents data=sashelp.class out=out1 noprint;
 run;


出力データセット


  • 「out=」に出力先のデータセットを指定
  • 「noprint」で結果ビューアへの表示を抑制(データセットへの出力のみで、結果ビューアへの表示は不要なので)
  • 注意点:例①で紹介した「varnum」を指定しても、出力データセットには影響しません(定義されている順番にソートしてくれない)
  • ちなみに出力データセットの変数VARNUMには、定義順の番号が入ってるので、これをPROC SORTで使って定義順にソート出来ます

proc sort data=out1;
   by varnum;
run;


2015年2月24日火曜日

PROC CONTENTSのSHORTオプションはアイディア次第で役に立ちそう。




CONTENTSプロシジャは、データセットの変数定義を出力できますが、、

*** サンプルデータ作成 ;
data DT1;
   retain A C B D  1;
run;

  A  
C
  B  
 D 
  1
  1  
  1  
  1  


*** 変数名を出力 ;
proc contents data=DT1  short  varnum ;
run;




  • SHORT」で出力が簡易的な「変数名のリスト」になります。
  • VARNUM」または「ORDER=VARNUM」で、データセットに格納されてる順 (上の例では「A C B D」の順) で変数名のリストが出力されます。


注意
  • 「SHORT」で出力する「変数名のリスト」の文字が長すぎると、文字が切り捨てられてログにWARNINGが出るらしいです。詳細はリファレンスを参照下さい。
  • 話それるけど、PROC CONTENTSの「OUT=オプション」で変数定義をデータセットに出力できますが、「SHORT」「VARNUM」「ORDER=」といったオプションの機能は「OUT=」で出力するデータセットには効力がないのでご注意を。





このオプション使えそうです。たとえば、、

*** 全変数名を(データセットに格納されてる順で)1つのマクロ変数に格納する ;
ods output PositionShort = OUT1;
    proc contents data=DT1  short  varnum;
    run;
ods output close;

data _NULL_ ;
    set OUT1 ;
    call symputx("VARS", VARIABLES);
run;

%put &VARS;

ログ
A C B D




あとデータステップ100万回のSASYAMAさんから、以下のように全変数名をアルファベット順で1つのマクロ変数に格納したい場合に役に立ったとコメントいただきました。なるほど~。
(すみません、色々いじってたら肝心のSASYAMAさんのコメント消してしまっていました。。)

*** 全変数名を(アルファベット順で)1つのマクロ変数に格納する ;
ods output VariablesShort = OUT2;
    proc contents data=DT1  short  order=casecollate;
    run;
ods output close;

data _NULL_ ;
    set OUT2;
    call symputx("VARS2", VARIABLES);
run;

%put &VARS2;

ログ
A B C D


  • 「ORDER=CASECOLLATE」でアルファベット順にしています。
  • また、「VARNUM」とか「ORDER=」のオプション設定値によって、「ODS OUTPUT」の出力オブジェクトの名前が「PositionShort」だったり「VariablesShort」だったり変わるみたいなのでご注意を。



2014年9月4日木曜日

変数名を取得する方法 [まとめ]




変数名を取得する方法は沢山ありますが、知ってる方法すべてあげてみようと思います。

取得した変数名をマクロ変数に入れたい場合は
変数値をマクロ変数に格納する方法「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 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.;
   if 0 then 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.;
       if 0 then 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」を別の名前に変えて下さい。


        2014年5月13日火曜日

        CONTENTS,DELETEプロシジャでは「ライブラリ名._ALL_」という書き方が出来る。



        CONTENTSとDELETEプロシジャではDATA = ライブラリ名._ALL_という書き方があるのをご存知でしょうか。
        どういったものか、例をみていきましょう。



        使用するダミーデータを作成

        data DT1 DT2 DT3;
          A=1;
        run;



        「ライブラリ名._ALL_」と指定してみる

        *** 1. CONTENTSプロシジャの例 ;
        proc contents data=WORK._ALL_ out=OUTC  noprint;
        run;

        ・指定したライブラリにある全てのデータセットとVIEWのコンテンツ情報を取得して、データセットに出力することが可能。



        *** 2. DELETEプロシジャの例 ;
        proc delete  data=WORK._ALL_;
        run;

        ・指定したライブラリにある全データセットを削除することが可能。