2022年11月29日火曜日

SQLプロシジャのINTO句の注意点


SQLのINTO句を使用する際の注意点を2つ紹介したいと思います。

 

1. 変数にフォーマットが割り当てられている場合

data DT1;
  format X yymmdd10.;
  X=1;
run;

proc sql noprint;
  select X into :X trimmed
  from DT1;
quit;
%put &X;

ログ
1960-01-02

マクロ変数にはフォーマットをあてた値が格納されるようです。この挙動、SASのリファレンスに書いてない気がする。。


もし、フォーマット値ではなく、変数値をマクロ変数に格納したい場合、
事前にフォーマットを除いておくか、もしくは数値変数ならデータに応じた適切な長さのBESTフォーマットを「FORMAT=」で便宜的にあてるなどの対応が必要になります。

proc sql noprint;
  select X format=best16. into :X trimmed
  from DT1;
quit;
%put &X;

ログ
1


2. 数値変数かつフォーマットが割り当てられていない場合

data DT2;
  X=123.456789;
run;

proc sql noprint;
  select X into :X trimmed
  from DT2;
quit;
%put &X;

ログ
123.4568

デフォルトの挙動として「BEST8.」の出力形式で格納されるようです。

状況によっては、もとの数値がだいぶ削られちゃいますね(これはINTO句に限ったことではないですが。。)


2022年7月9日土曜日

【PROC FORMAT】CNTLIN=オプションの落とし穴



まず、前提知識として「PROC FORMAT入門9 : CNTLIN=オプション 」をご参照下さい。


そして、ここから本題。以下の例をご覧ください。


失敗例

①まず「データセット」から「フォーマット」を生成

data FMT;
input FMTNAME:$10. START:$10. LABEL:$20.;
cards;
$TEST_ OTHER その他
;


proc format cntlin=FMT;
run;


②実データに先ほどのフォーマットを当ててみる。

data TEST;
input X:$20.;
cards;
OTHER
.
;


data TEST2;
 set TEST;
 format X $TEST_.;
run;


あれ?!

フォーマット当てた結果、2行目の欠損値に「その他」が当てられてしまってる?!


解説

「CNTLIN=」に使用するフォーマット生成用のデータセットに注目


実は上の "OTHER" が、範囲指定としての「OTHER」として解釈されてしまってます(範囲指定?という方は「PROC FORMAT入門3 : 範囲の指定」を参照)

要は、以下のようにFORMATプロシジャで①みたいな定義をしたつもりが、②の定義をしてしまった、ということ。

proc format; /* ① */
 value $TEST_
 "OTHER" = "その他"
 ;
run;

proc format; /* ② */
 value $TEST_
 OTHER = "その他"
 ;
run;

余計なことをしてますね。。


ちなみに、"OTHER" 以外にも、FORMATプロシジャの予約語的なキーワードは気を付けた方が良いです(色々実験してみたところ、"LOW", "HIGH" なども同様に範囲指定の意味として解釈されてしまいました。たぶん他にもあると思います)



解決策

今回の例では "OTHER" を範囲指定の意味ではないと明示してあげる必要があります。
なので、以下のようにHLOという変数を作ってNullに設定しておけば良いはず。
(HLO?という方は「PROC FORMAT入門9 : CNTLIN=オプション」を参照)

data FMT;
input FMTNAME:$10. START:$10. LABEL:$20. HLO:$1.;
cards;
$TEST_ OTHER その他 .
;


proc format cntlin=FMT;
run;



上でフォーマットを作り直したので、再度このフォーマットをあてたデータセットを見てみましょう。

はい!さっきまで2行目の欠損値が「その他」になっちゃってましたが、今度は問題なさそうです。


最後に

私が把握しているのは "OTHER", "LOW", "HIGH" のみで、その他にFORMATプロシジャの予約語的なキーワードに引っかかるものがあるかもしれません。

今回の場合だと"OTHER"に対してHLOという変数を作ってNullに設定することで解決しましたが、その他の私が把握していないキーワードに対して、各自SASのリファレンスや「PROC FORMAT入門9 : CNTLIN=オプション」などを参考にして、他の必要な変数を設定してあげる必要があります。



2022年6月29日水曜日

SASで花火を描く




暑中お見舞い申し上げます。




SASで花火描いてみました。三角関数をつかってるだけの単純なプログラムです。

/* 花火描画用データ */
data fireworks;
 rad = constant('pi')/180;
 call streaminit(777);
 do i = 1 to 5;
  xpos = rand("uniform",-30,30);
  ypos = rand("uniform",-30,30);
  do rmax = 0, 36;
  do r = 0 to rmax by 4;
  do a = 0 to 360 by 15;
    x=cos(a*rad)*r+xpos;
    y=sin(a*rad)*r+ypos;
    output;
  end;
  end;
  end;
 end;
run;

/* 花火描画 */
title;
ods graphics / height=20cm width=20cm;

options animation=start animduration=1.2 printerpath=gif;
ods noresults;
ods printer file="出力するGIFファイルのフルパスをここに指定。ファイル名は「fireworks.gif」とか適当に" ;

%macro m_fireworks(i=,color=);
 proc sgplot data=fireworks aspect=1 noautolegend;
  styleattrs wallcolor=midnightblue;
  scatter x=x y=y / markerattrs=(symbol=circlefilled color=&color size=0.1cm );
  xaxis min=-50 max=50 display=none;
  yaxis min=-50 max=50 display=none;
  inset "Summer Greetings to All."/ position=bottom textattrs=(color=lightblue size=25cm family="Arial");
  by rmax;
  where i=&i;
 run;
%mend;
%m_fireworks(i=1,color=yellow);
%m_fireworks(i=2,color=skyblue);
%m_fireworks(i=3,color=lightgreen);
%m_fireworks(i=4,color=yellow);
%m_fireworks(i=5,color=lightpink);

ods printer close;
ods results;
options animation=stop;

ods graphics / reset=all;


2022年3月31日木曜日

「PUT "WARNING-"」みたいな書き方。



今回は、以下で紹介した記事のおまけ的内容。


最初に

上の記事のおさらい。

以下サンプルのように「NOTE」「WARNING」「ERROR」のいずれかのキーワードとコロン「:」をつけてPUTすると、ログ上に色つきの独自メッセージを表示できる。

data _null_;
  put "NOTE:    独自メッセージ1";
  put "WARNING: 独自メッセージ2";
  put "ERROR:   独自メッセージ3";
run;

ログ


本題 

上の例でコロン(:)ではなくハイフン(-)に変えると、、

data _null_;
  put "NOTE-    独自メッセージ1";
  put "WARNING- 独自メッセージ2";
  put "ERROR-   独自メッセージ3";
run;

ログ

「NOTE」「WARNING」「ERROR」のキーワード無しで色つきのメッセージを出力できます。


活用例

これは、以下のような使い方が出来ます。

data _null_;
  put "WARNING: 独自メッセージ1";
  put "WARNING- 独自メッセージ1の続き";
run;

ログ

WARNINGメッセージを改行しているように見せることが出来ます。


ただし、1つだけ残念ポイント。

%PUTで同様のテクニックを使おうとすると、、

%put WARNING: 独自メッセージ1;
%put WARNING- 独自メッセージ1の続き;

ログ

ログを見てみると、間にプログラムの文が挟まっていて、WARNINGメッセージが分割されて見えてしまうところ。残念よ。


2022年2月11日金曜日

「PUT 変数名=」という書き方


PUTステートメントの基本的なテクニックの紹介。


基本的なテクニック

data test;
  set sashelp.class;
  if age=13 then put height=;
run;

ログ
 height=56.5
 height=65.3
 height=62.5

「変数名=」という書き方で、例のように先頭に「変数名=」という書式のテキストを追加できます。



以下のように、ちょっと勿体ない書き方をしがち。


ちょっと勿体ない例

data test;
  set sashelp.class;
  if age=13 then put "height=" height;
run;

ログ
 height=56.5
 height=65.3
 height=62.5

勿体ない!