2019年2月28日木曜日

「OPTIONS NOBYLINE」でBYグループ毎に改ページを挿入する





システムオプション「BYLINE」「NOBYLINE」を紹介。



「BYLINE」の紹介

*** サンプルデータ ;
proc sort data=sashelp.class out=class;
    by age;
run;

*** 「BYLINE」でPROC MEANSを実行 ;
options byline;
proc means data=class;
    var height;
    by age;
run;


「BYLINE」だと、BYグループごとにBY値が表示されます。
(デフォルトではこの設定になっています)




「NOBYLINE」の紹介

*** 「NOBYLINE」でPROC MEANSを実行  ;
options nobyline;
proc means data=class;
    var height;
    by age;
run;


「NOBYLINE」だと、BYグループごとのBY値が表示されません。
その代りBYグループごとに改ページが入ります。



でもこれだとBYグループごとのBY値が表示されないんで、Ageがどの値のときの出力結果なのかわかりづらいですよね。
そこで、TITLEステートメントの小技「#BYLINE」というのを使うと、

options nobyline;
title "#byline";

proc means data=class;
    var height;
    by age;
run;



TITLEにBY値が表示されるようになり、分かりやすい出力結果になりました!
「#BYLINE」のほかにも「#BYVAR」とか「#BYVAL」ってのもあるんで、そこんとこ次回詳しく紹介します!


2019年2月22日金曜日

グラフのマーカーや線などの属性をGROUP毎に設定する【Attribute Map Dataset 編】



「Attribute Map Dataset」を利用して、「SGPLOT」や「GTL」でマーカーや線などの属性を定義する方法を紹介します。




まず、以下の可愛らしいグラフをご覧ください。




年齢ごとに、マーカーの種類や色を変えて散布図を描いてます。
どうやってるか解説していきたいと思います。





Step1. 「Attribute Map Dataset」を作成する


まずグループ(年齢)毎にマーカーの種類や色を定義したデータセットを作ります。
(このデータセットを「Attribute Map Dataset」と呼びます)

data MYMAP;
input ID:$10. VALUE:$10. MARKERCOLOR:$10. MARKERSYMBOL:$30. MARKERSIZE:8.;
cards;
myid 11 blue CircleFilled 11
myid 12 red  StarFilled 11
myid 13 yellow TriangleFilled 11
myid 14 lightgreen DiamondFilled 11
myid 15 black SquareFilled 11
myid 16 skyblue TriangleDownFilled 11
;



たとえば1OBS目では以下を設定しています。
  • グループの値(今回は年齢)が「11」の時に、
  • マーカー色「blue」
  • マーカーの種類「CircleFilled」
  • マーカーサイズ「11」



データセットには以下のような変数を含めることが出来ます(一部抜粋)

変数設定内容備考
ID文字ID値
VALUE文字グループの値・例えば年齢をグループにするのであれば年齢の値
グループにする変数にFORMATが割り当てられている場合、FORMATを当てた後の値を指定する事。

例えば 11 = "11歳" のようにFORMATが当てられている場合、"11歳" の方を指定する。
FillColor文字グラフの中の色・棒グラフの中の色など
MarkerColor 文字マーカーの色・散布図のマーカーの色など
MarkerSize数値マーカーのサイズ・散布図のマーカーのサイズなど
MarkerSymbol文字マーカーの種類・散布図のマーカーの種類など
LineColor文字線の色・折れ線グラフの線の色など
LinePattern数値/
文字
線の種類・折れ線グラフの線の種類など
LineThickness数値線の太さ・折れ線グラフの線の太さなど
…等々

(「ID」と「VALUE」は必ずデータセットに含める必要があり、それ以外は任意)





Step2. グラフを描画


Step1で作った「Attribute Map Dataset」をSGPLOTまたはGTLで参照してグラフを描くことが出来ます。

注意:
SAS9.4M3より前のバージョンでは、この機能 (Attribute Map Dataset) と一緒に、PLOTステートメント (SCATTERやSERIESなど) でも属性を定義している場合、結果のプロット部分と凡例部分の属性が一致していないおかしな状態になってしまうことがある?らしいので注意。

  • SGPLOTで描画
proc sgplot data=SASHELP.CLASS dattrmap=MYMAP;
   scatter x=HEIGHT y=WEIGHT / group=AGE grouporder=ascending attrid=myid;
run;

  • group=」でAGE毎に散布図を描いています。
  • dattrmap=」で参照する Attribute Map Dataset を指定。
  • attrid=」で参照する Attribute Map Dataset のID値を指定。



  • GTLで描画
proc template ;
     define statgraph MYTEMP ;
     begingraph;

     layout overlay;
          scatterplot x=HEIGHT y=WEIGHT / group=AGE grouporder=ascending name="leg1";
          discretelegend "leg1" / title="Age";
     endlayout;

     endgraph;
     end;
run;

proc sgrender data=SASHELP.CLASS template=MYTEMP dattrmap=MYMAP;
     dattrvar AGE="myid";
run;


  • group=」でAGE毎に散布図を描いています。
  • dattrmap=」で参照する Attribute Map Dataset を指定。
  • dattrvar」でグループ変数AGEに対応づけるAttribute Map DatasetのID値を指定。



2019年2月14日木曜日

データセット間で同じ変数名があるかチェックする方法





たまにタイトルにあるようなチェックをかけたい事ってありますよね。
色々方法はあると思いますが、今回はPROC SORTによる解法を載せておきます。



サンプルデータ

data TEST1;
   aa=1; bb=2;
run;

data TEST2;
   Aa=1; bb=2; cc=3;
run;

data TEST3;
   bb=2; xx=4;
run;







ここで、WORKライブラリのデータセットTEST1、TEST2、TEST3に同じ変数名があるかを確認したいと思います。



PROC SORTでの解法例

%upcase(
   proc sort data=sashelp.vcolumn out=OUT1 nouniquekey sortseq=linguistic(strength=primary);
       by name;
       where libname="WORK" and memname in ("TEST1","TEST2","TEST3");
   run;
)


結果がデータセットOUT1に出力されます。
「aa」と「bb」が変数名として重複してるってことですね。



ざっくり解説

  • 変数定義情報は「SASHELP.VCOLUMN」から取得しています。
  • PROC SORTの「NOUNIQUEKEY」をうまく利用しています。
  • 「sortseq=なんちゃらかんちゃら」の部分はマニュアル分かりづらくてちゃんと調べきれてないですが、これを指定すると日本語をソートする場合だと「あ」と「ア」、「ア」と「ア」、「B」と「b」などを同じとみなすようになります。
  • 今回の場合は変数名が大文字だったり小文字だったりしても同じものとみなしたいんで指定してます。
  • プログラム青文字部分にチェック対象のライブラリ名とデータセット名を指定します。



2019年2月7日木曜日

2軸グラフの描き方【GTL編】




YAXIS=オプション」で、左右のY軸を使うことが出来ます。



* 使用するデータの準備 ;
proc sort data=SASHELP.ELECTRIC  out=ELECTRIC;
    by YEAR;
    where CUSTOMER = "Residential";
run;

* 2軸グラフを描く ; 
proc template ;
    define statgraph MYTEMP ;
    begingraph;
        layout overlay;
               seriesplot x=YEAR y=COAL                / yaxis=y  lineattrs=(color=blue) name="n1";
               seriesplot x=YEAR y=NATURALGAS / yaxis=y2 lineattrs=(color=red)  name="n2";
               discretelegend "n1" "n2";             
        endlayout;
    endgraph;
    end;
run;

proc sgrender data=ELECTRIC template=MYTEMP;
run;



例では、2つの折れ線を書いて、X軸はYEARを用い、
  • 「YAXIS=Y」で左側のY軸にCOALを設定
  • 「YAXIS=Y2」で右側のY軸にNATURALGASを設定
としています。


ちなみにX軸も「XAXIS=X2」と指定すれば、上側のX軸を使うことも出来ますよ。


2019年2月6日水曜日

2軸グラフの描き方【SGPLOT編】




Y2AXISオプション」で、右側のY軸を使うことが出来ます。



* 使用するデータの準備 ;
proc sort data=SASHELP.ELECTRIC  out=ELECTRIC;
    by YEAR;
    where CUSTOMER = "Residential";
run;

* 2軸グラフを描く ; 
proc sgplot data=ELECTRIC;
    series x=YEAR y=COAL               / lineattrs=(color=blue);
    series x=YEAR y=NATURALGAS / lineattrs=(color=red)  y2axis ;
    xaxis type=discrete;
run;



例では、2つの折れ線を書いて、X軸はYEARを用い、
  • 左側のY軸にCOALを設定
  • 右側のY軸にNATURALGASを設定
としています。


ちなみにX軸も「X2AXIS」と指定すれば、上側のX軸を使うことも出来ますよ。



2019年2月1日金曜日

FIRSTOBSオプションの落とし穴




今回は以下2つの記事に関連した内容です。

FIRSTOBS=, OBS=, WHERE を組み合わせたときの挙動
行削除の落とし穴



では本題。まずは適当にサンプルデータ。

data dt1;
  do x="a","b","c";
    output;
  end;
run;


1行目をSQLプロシジャで削除してみます。

proc sql;
  delete from dt1 where x="a";
quit;


すると、削除したオブザベーション番号の「1」が欠番になってしまいます。
これは上の方で示した2個目のリンク記事で紹介済みですね。



この使用できるオブザベーションが歯抜けになってしまう事で、FIRSTOBS=オプションも影響を受けてしまうようです。
たとえば「FIRSTOBS=2」として読み込んだ場合、、

proc print data=dt1 (firstobs=2);
run;

「x="c"」だけがprintされないとおかしいですよね。



SETしなおせば歯抜けが直るんで、想定通りになります。

data dt1;
   set dt1;
run;

proc print data=dt1 (firstobs=2);
run;