2018年7月14日土曜日

古くて可愛い PROC CHART と PROC PLOT




PROC CHART と PROC PLOT は簡単にいうとアスキーアートのようなグラフを作る事が出来ます。



今でこそPROC SGPLOTとかで綺麗なグラフを作れるんで、マニュアルに載っててもスルーされがちですが、味があって私は結構好きです。
昔のSASの本にはよく載ってましたね。


何個か例を見ていきましょう。



options ls=100 ps=40;

proc chart data=sashelp.class;
   vbar age /  type=freq discrete;
run;



味がありますね。




proc chart data=sashelp.class;
   block age / type=freq discrete;
run;


可愛いです。



proc chart data=sashelp.class ;
    pie age / type=freq discrete;
run;


狂気を感じるけど可愛いです。



proc plot data=sashelp.class;
   plot height*weight $name;
run;
quit;


PROC PLOTも味がありますね~。


これからも使っていきたいです。



2018年7月4日水曜日

【SAS9.3以前のBug】E8601DTインフォーマットで正しく変換できないことがある。



今回の記事はSAS9.3以前で発生するバグの話です。
(9.4では解消されてます)


CDISC対応でADaMのデータセットをよく作る方なら既にご存知かもしれません。
SAS社の Problem Note にE8601DTインフォーマットのバグについての記載があります。

Problem Note 43743: E8601DT informat might read beyond its intended boundary
http://support.sas.com/kb/43/743.html



再現してみましょう。


data TEST;
    length X1 X2 $16.;
    X1 = "2018-01-01T10:00";
    X2 = ":15";

    format Y e8601dt.;
    Y  = input( X1, e8601dt. );
run;

SAS9.4での実行結果
  X1 
  X2  
  Y  
 2018-01-01T10:00  :15  2018-01-01T10:00:00 


SAS9.3での実行結果(Bug)
  X1 
  X2  
  Y  
 2018-01-01T10:00  :15  2018-01-01T10:00:15 


9.3で実行すると、X1とX2が合体した日時がYに格納されてしまいました。



内部の動きとして、E8601DTインフォーマットはデフォルトで入力データから19文字読み込もうとします。
しかしX1はlengthが16しかないので、残りの3文字をX2から読み込んできちゃうという暴挙にでるわけです。


解決策
このバグが解消されているSAS9.4で実行するのが手っ取り早いです。

9.3なら、変換する変数のlengthを16じゃなくて19に設定しとくとか、
または以下のような感じでINPUT関数で変換する時に、後ろに半角スペースを3文字分くっつけて、無理矢理19文字にするっていうのはどうでしょうか。これらは検証してないんでうまくいくかは保証できないです。

  if X1 ^="" then Y  = input( X1 || "   ", e8601dt. );


よーわからんですね。気をつけましょう。


2018年6月29日金曜日

【小ネタ】データセットオプション「DROP=」「KEEP=」「RENAME=」の後に変数を指定しなくてもERRORにならない。




以下のように、データセットオプションの「drop=」「keep=」「rename=()」に変数を指定しなくても、ERRORになりません。

data out1;
   set sashelp.class ( drop= keep= rename=() );
run;



変数の指定がないので、これらのデータセットオプションは何もしません。




私はよく以下のような使い方をしています。
%macro test( _drop=, _keep=, _rename= );

    data out1;
      set sashelp.class ( drop=&_drop  keep=&_keep  rename=(&_rename) );
    run;

%mend;




マクロ実行時にdropしたい変数、keepしたい変数、renameしたい変数があれば、それらを指定できるようにし、指定がない場合は何もしない、という分岐を作る事ができます。



たとえば以下を実行すると、drop=, keep=, rename=をしません。

%test( )



以下実行すると、ageをkeepします。

%test( _keep=age )




2018年6月14日木曜日

PROC FORMAT入門8 : CNTLOUT=オプション




「CNTLOUT=オプション」で、FORMATカタログの中身をデータセットに出力することが出来ます。




構文

PROC FORMAT  LIBRARY=ライブラリ.カタログ名  CNTLOUT=出力先データセット ;
       SELECT  出力するフォーマットを列挙;
RUN;


  • 「LIBRARY=ライブラリ名」というようにカタログ名を省略した場合、ライブラリ内の「FORMATS」という名前のカタログがデフォルトで選択されます。
  • SELECTステートメントを省略するとカタログ内の全フォーマットが選択されます。




例

proc format;
   value TEST1_
       1 = "MALE"
       2 = "FEMALE"
   ;
   value $TEST2_
       "Y" = "YES"
       "N" = "NO"
   ;
run;

proc format lib=WORK cntlout=OUT1;
run;



フォーマット「TEST1_」と「TEST2_」が、CNTLOUT=オプションで作成されたデータセットにそれっぽい感じで格納されていることが分かるかと思います。



出来たデータセットの各変数について、以下にざっくり説明しておきます。



CNTLOUT = データセットの各変数の説明

 変数名 型 内容 
 FMTNAME  文字   フォーマット名
 START 文字 開始値
 END 文字 終了値
 LABEL 文字 出力値
 MIN 数値 MIN=オプション値 
 MAX 数値 MAX=オプション値
 DEFAULT
 数値 DEFAULT=オプション値 
 LENGTH  数値 LENGTH=オプション値 。。とリファレンスに書いてありますが、
 そんなオプション存在しないと思われるので詳細不明
 FUZZ   数値 FUZZ=オプション値
 PREFIX   文字 PICTUREフォーマットのPREFIX=オプション値 
 MULT 
 数値
 PICTUREフォーマットのMULTIPLIER=オプション値
 FILL  文字 PICTUREフォーマットのFILL=オプション値
 NOEDIT   数値 PICTUREフォーマットのNOEDITオプションが有効かどうか
 (1=有効 0=無効)
 TYPE 

 文字

 フォーマットの種類
  N = 数値フォーマット
  C = 文字フォーマット
  I = 数値インフォーマット
  J = 文字インフォーマット
  P = PICTUREフォーマット

 SEXCL

 文字

 開始値の取扱い
 ("Y"=開始値を含めない "N"=開始値を含める)

 EEXCL  

 文字

 終了値の取扱い
 ("Y"=終了値を含めない "N"=終了値を含める)

 HLO

 文字

 開始値・終了値の追加情報 (すごく重要な変数)

  O = OTHER

  L = LOW
  H = HIGH
  R = PICTUREフォーマットのROUNDオプション
  ...等。詳細はリファレンスを参照 


 (組み合わせて使用します。例:Low-High…LH)


 DECSEP  文字 PICTUREフォーマットのDECSEP=オプション値
 DIG3SEP 文字 PICTUREフォーマットのDIG3SEP=オプション値
 DATATYPE  文字 PICTUREフォーマットのDATATYPE=オプション値
 LANGUAGE 文字 PICTUREフォーマットのLAUNGUAGE=オプション値






次に色々なフォーマットをCNTLOUT=でデータセットに出力して、どんな感じのデータが出来るか見てみます。

例2

proc format;
   value TEST1_
      1 = "MALE"
      2 = "FEMALE"
   ;
   value $TEST2_
      "Y" = "YES"
      "N" = "NO"
   ;
   value TEST3_
      1 - 3 = "1~3"
      other = "その他"
   ;
   invalue TEST4_
      "MALE"     = 1
      "FEMALE" = 2
   ;
   invalue $TEST5_
      "Y"    = "YES"
      "N"    = "NO"
   ;
   picture TEST6_ (default=3)
     low -< 0 = '00' (prefix="-")
     0 - high = '00'
   ;
   picture TEST7_ (round)
      low - high = '009.00%'
   ;
   picture TEST8_ (default=10)
      low - high = '%Y_%0m_%0d' (datatype=datetime)
   ;
run;


proc format lib=WORK cntlout=OUT1;
run;


結果は以下。画像をクリックすると拡大されます。



2018年6月7日木曜日

特定のシステムオプションをSAS起動時の設定に戻す【GETOPTION関数の使用例】





この前、以下GETOPTION関数の記事を書きましたが、今回は使用例を紹介します。
【GETOPTION関数】システムオプションの設定値を取得したりする。



例えば、PAGESIZEを200に設定したとします。

  options pagesize=200;




後から、このPAGESIZEをSAS起動時の設定に戻したい場合、以下のように書くだけでOK。

  options %sysfunc( getoption(pagesize,startupvalue,keyword) );


%SYSFUNCってなんだって人は以下も参照ください。
データステップ外で関数を使えるようにする「%SYSFUNC」その1



一応ちゃんと設定がSAS起動時の状態に戻ったか確認してみましょう。

  %put NOTE: OPTIONS %sysfunc( getoption(pagesize,keyword) ) に設定されています;

ログ
 NOTE: OPTIONS PAGESIZE=60 に設定されています

はい、私の環境だと PAGESIZE=60 なんで戻ってますね。



2018年6月2日土曜日

【GETOPTION関数】システムオプションの設定値を取得したりする。




GETOPTION関数でシステムオプションの設定値を取得できます。
試しにPAGESIZEオプションの設定値を取得してみます。



オプションの設定値を取得する例

options pagesize=200;

data test;
   length op $20.;
   op = getoption("pagesize");
run;

  op  
  200 

現在のPAGESIZEの設定値「200」を取得できました。
そして、この関数はこれだけじゃないですよ!オプションの取得方法も細かく指定できます。




「オプション名=設定値」の形式で取得する。

  op = getoption("pagesize","keyword");

  op  
  PAGESIZE=200 

PAGESIZEを設定する時は以下の赤文字部分の書式で書きますが、この部分が取得できるというわけです。

options pagesize=200;





SAS起動時の設定値を取得する。

  op = getoption("pagesize","startupvalue");

  op  
  60 





オプションの取得方法を複数指定する。

  op = getoption("pagesize","startupvalue","keyword");

  op  
  PAGESIZE=60 

SAS起動時の設定値をOPTIONSステートメントの書式で取得しています。



一番使えそうなのはこの辺ですかね、他にも色々指定方法があるんで、詳細はマニュアルをご覧くださいね。


2018年5月24日木曜日

SASユーザー間の情報交換サイト「SAS Japan Discussion」





ついにオープンしました!待ってました!

SAS Japan Discussion
https://communities.sas.com/t5/SAS-Japan-Discussion/bd-p/japanforum-board



「https://communities.sas.com」はSAS社のサイトで前から存在してましたが、やり取りは全部英語でした。そこに今回日本語用のページが用意された感じです。

質問や回答したい場合は、アカウントを登録します。

いやー、うれしいです。
あとはちゃんと回答者がついて軌道に乗ってくれるかですね。。私も微力ながら応援していけたらと思います。