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

2020年2月6日木曜日

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



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



と、その前に、以前「Attribute Map Dataset」を紹介しました。
グラフのマーカーや線などの属性をGROUP毎に設定する【Attribute Map Dataset 編】


今回はもう1つの方法として「Attribute Map Statement」を紹介していきます。
(※Attribute Map StatementはGTLのみの機能となります)



さっそくサンプルプログラム

proc template ;
     define statgraph MYTEMP ;
     begingraph;

     /* Attribute Map を定義 */
     discreteattrmap name="mymap";
        value "11" "12" / markerattrs=(color=blue    symbol=starFilled        size=11);
        value "13" "14" / markerattrs=(color=yellow symbol=TriangleFilled  size=11);
        value other       / markerattrs=(color=red      symbol=CircleFilled     size=11);
     enddiscreteattrmap;

     /* 「Attribute Map」と「グループ変数」を関連付ける */
     discreteattrvar  var=age attrmap="mymap" attrvar=myvar;

     /* 「Attribute 変数」の使用 */
     layout overlay;
          scatterplot x=HEIGHT y=WEIGHT / group=myvar grouporder=ascending name="leg1";
          discretelegend "leg1" / title="Age";
     endlayout;

     endgraph;
     end;
run;

proc sgrender data=SASHELP.CLASS template=MYTEMP;
run;


上の例では以下のような設定をしています。
  • 年齢(AGE)をグループ変数として、マーカーの種類と色を以下に設定
  • AGEが「11」「12」の時、青色の星マーク
  • AGEが「13」「14」の時、黄色の三角マーク
  • AGEが上記以外の時、赤色の丸マーク


ではどのように設定しているか見ていきましょう。




Step1. 「Attribute Map」を定義する


まずは、グループ変数の値にどういった書式(属性)を割り当てるのか?を定義します。

構文
DISCRETEATTRMAP  NAME="Attribute Mapの名前";
     VALUE  "グループ変数の値1"  /  属性;
     VALUE  "グループ変数の値2"  /  属性;
     …
ENDDISCRETEATTRMAP;


今回は以下のように書いています。

discreteattrmap name="mymap";
   value "11" "12" / markerattrs=(color=blue    symbol=starFilled        size=11);
   value "13" "14" / markerattrs=(color=yellow symbol=TriangleFilled  size=11);
   value other       / markerattrs=(color=red      symbol=CircleFilled     size=11);
enddiscreteattrmap;

  • 「mymap」というAttribute Map を定義
  • グループ変数の値が「11」「12」の時、青色の星マーク
  • グループ変数の値が「13」「14」の時、黄色の三角マーク
  • グループ変数の値が上記以外の時、赤色の丸マーク


ちなみに属性には「マーカー」や「塗りつぶし」といった設定を行う以下の属性オプションが用意されています(GTL書いたことある人ならお馴染みの書き方)

  • MARKERATTRS=()
  • FILLATTRS=()
  • LINEATTRS=()
  • TEXTATTRS=()


重要ポイント

グループにする変数にFORMATが割り当てられている場合、FORMATを当てた後の値を指定する事。
例えば年齢をグループ変数とする場合、11 = "11歳" のようにFORMATが当てられている場合、"11歳" の方を指定する。

discreteattrmap name="mymap";
   value "11歳"  / markerattrs=(color=blue symbol=starFilled  size=11);
enddiscreteattrmap;




Step2. 「Attribute Map」と「グループ変数」を関連付ける


次に、先ほど定義した「Attribute Map」と「実際のグループ変数」を関連付けます。


構文
DISCRETEATTRVAR
    VAR              = グループ変数
    ATTRVMAP  = "グループ変数と関連付けるAttribute Map"
    ATTRVAR     = グループ変数とAttribute Mapの関連付けに対して、任意の名前を定義
;


今回は以下のように書いています。

discreteattrvar var=age attrmap="mymap" attrvar=myvar ;

「グループ変数=AGE」と「Attribute Map="mymap"」を「myvar」という名前(Attribute変数)で関連付けています。



Step3. 「Attribute変数」の利用


あとはPLOTするときに、グループ変数として「Attribute変数」を指定すればOK

scatterplot x=HEIGHT y=WEIGHT / group=myvar grouporder=ascending ;

これで、Attribute Mapの定義に基づいてマーカーの種類や色などの属性を展開してPLOTしてくれます。

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



2019年2月22日金曜日

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



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




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




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





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


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

data MYMAP;
input ID:$20. VALUE:$30. MARKERCOLOR:$30. 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
;

proc sort data=MYMAP;
   by ID;
run;



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



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

変数型設定内容備考
ID文字ID値PROC SORTでIDの順にソートする事をお勧めします。

例えば、各オブザベーションのID値の順番が "myid", "myid2", "myid" のように異なるID値が間に入ると正しく動作しません。

VALUE文字グループの値例えば年齢をグループにするのであれば年齢の値を指定

・グループにする変数にFORMATが割り当てられている場合、FORMATを当てた後の値を指定する事。

例えば 11 = "11歳" のようにFORMATが当てられている場合、"11歳" の方を指定する。

・"_OTHER_" と "_MISSING_" はSAS内部での予約語なので注意。バージョン毎に予約語が増えるかも

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値を指定。
  • 以下のように同じグループ変数に異なるID値を割り当てるような事は出来ません(正しく動作しない&ログにWARNINGが出る)  

scatter x=XX1 y=YY1 / group=AGE attrid=myid;
scatter x=XX2 y=YY2 / group=AGE attrid=myid2;



  • 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値を指定。
  •   以下のように同じグループ変数に異なるID値を割り当てるような事は出来ません(正しく動作しない)

dattrvar AGE="myid" AGE="myid2";



2016年12月15日木曜日

GTLで線形軸(LINEAROPTS=オプション)の最小・最大値を設定する際の注意点




よく勘違いする部分なので、まとめておきます。
ここでは「LAYOUT OVERLAY」内で線形軸を設定する場合の説明になります。



まずは軸設定の失敗例を2つ。

失敗例1
「TICKVALUESEQUENCE」や「TICKVALUELIST」で目盛を設定できますが、
たとえば以下の通り目盛「0~30」、目盛間隔「1」 と設定すると、、

proc template ;
   define statgraph MYGRAPH;
      begingraph;
      layout overlay / xaxisopts=(linearopts=(tickvaluesequence=(start=0 end=30 increment=1)));
           scatterplot x=AGE y=WEIGHT;
      endlayout;
      endgraph;
   end;
run;

proc sgrender data=SASHELP.CLASS template=MYGRAPH;
run;



実際のデータ(Age)が「11~16」の範囲にあるため、目盛は0~30ではなく、11~16になっています。


失敗例2
では今度は、目盛 「12~14」、目盛間隔「1」 と設定した場合、

proc template ;
   define statgraph MYGRAPH;
      begingraph;
      layout overlay / xaxisopts=(linearopts=(tickvaluesequence=(start=12 end=14 increment=1)));
           scatterplot x=AGE y=WEIGHT;
      endlayout;
      endgraph;
   end;
run;

proc sgrender data=SASHELP.CLASS template=MYGRAPH;
run;



実際のデータ(Age)は「11~16」なので、軸は11~16の範囲まで設けられますが、目盛としては12~14が表示されます。



よく頂く質問が、『軸の最小・最大値を 「TICKVALUESEQUENCE」や「TICKVALUELIST」で設定したのに、うまく設定できない!』というものです。
上記で説明した通り、 「TICKVALUESEQUENCE」や「TICKVALUELIST」は目盛を設定するだけなので、軸の範囲(最小・最大)も別途設定する必要があります。



以下に軸の設定例を2つ紹介します。
【シチュエーション】軸の最小・最大を0~30、目盛間隔を2に設定したい


軸の設定例1
「TICKVALUEPRIORITY=TRUE」を指定することで、「TICKVALUESEQUENCE」や「TICKVALUELIST」による目盛の最小・最大値を軸に含めることが出来ます。

proc template ;
   define statgraph MYGRAPH;
      begingraph;
      layout overlay / xaxisopts=(linearopts=(tickvaluepriority=true
                                                               tickvaluesequence=(start=0 end=30 increment=2)));
           scatterplot x=AGE y=WEIGHT;
      endlayout;
      endgraph;
   end;
run;

proc sgrender data=SASHELP.CLASS template=MYGRAPH;
run;

ただし「失敗例2」のように、
「TICKVALUESEQUENCE」や「TICKVALUELIST」で設定した目盛の範囲外に、実際のPLOTするデータがある場合、「TICKVALUEPRIORITY=TRUE」は効果なしです(結果は「失敗例2」の出力結果と同様、実際のPLOTするデータの範囲まで軸が拡張される)



軸の設定例2
「VIEWMIN」,「VIEWMAX」で軸の範囲(最小・最大)を設定し、「TICKVALUESEQUENCE」や「TICKVALUELIST」で目盛を設定する。

proc template ;
   define statgraph MYGRAPH;
      begingraph;
      layout overlay / xaxisopts=(linearopts=(viewmin=0 viewmax=30
                                                               tickvaluesequence=(start=0 end=30 increment=2)));
           scatterplot x=AGE y=WEIGHT;
      endlayout;
      endgraph;
   end;
run;

proc sgrender data=SASHELP.CLASS template=MYGRAPH;
run;

注意点として、
「VIEWMIN」「VIEWMAX」で軸の範囲(最小・最大)が固定されるので、実際のPLOTするデータが軸の範囲外にあっても、その範囲外のPLOT部分はグラフに表示されません。


最後に、
他のオプションとの組み合わせによって、今回紹介したオプションの機能が無効または挙動が変わるので、その辺りの細かい部分についてはリファレンスも確認してみて下さい。



2016年3月3日木曜日

箱ひげ図をかく 【GTL編】




GTLの詳細については、以下リンクをご覧ください。



BOXPLOTステートメントの構文


  BOXPLOT X=カテゴリ Y=分析変数 / オプション;


  • デフォルトでカテゴリ(X軸)は離散軸になりますが、ユーザー側で線形軸等に変えると、挙動が変わってしまいます。詳細はリファレンスを要確認。



オプション

  設定内容  指定   詳細設定
  箱ひげ図を横に寝かす 

  ORIENT =  HORIZONTAL  

    
  箱の幅

  BOXWIDTH  =  0~1

  
  箱の書式

  FILLATTRS  =  (詳細設定) 

  COLOR = 色

  ひげの書式

  WHISKERATTRS  =  (詳細設定) 

  COLOR = 色

  中央値の書式

  MEDIANATTRS  =  (詳細設定)

  COLOR = 色

  平均値の書式 

  MEANATTRS  =  (詳細設定)
  
  COLOR   = 色
  SYMBOL = 表示マーク  

  外れ値の書式 

  OUTLIERATTRS  =  (詳細設定)   

  SYMBOL = 表示マーク 
  

…etc ( 色々できるのでリファレンスを確認してみてください )



注意
  • オプションの組み合わせで挙動が変わる可能性あり。
  • デフォルトで出力される箱ひげ図のタイプ(箱、ひげ、外れ値等の定義)はリファレンスを要確認



1. 簡単な例

proc template ;
  define statgraph MYGRAPH;
      begingraph ;
         entrytitle "お魚の体重分布";
         layout overlay  ;
              boxplot x=SPECIES y=WEIGHT;
         endlayout;
       endgraph;
  end;
run;

proc sgrender data=SASHELP.FISH template=MYGRAPH;
run;



2.カスタマイズ

proc template ;
  define statgraph MYGRAPH;
      begingraph ;
         entrytitle "お魚の体重分布";
         layout overlay  ;
              boxplot x=SPECIES y=WEIGHT /
                            orient = horizontal
                            meanattrs = (color=black symbol=plus)
                            medianattrs = (color=black)
                            whiskerattrs = (color=black)
                            fillattrs = (color=white)
                            outlierattrs = (symbol=circlefilled)
                            boxwidth = 0.5
              ;
         endlayout;
       endgraph;
  end;
run;

proc sgrender data=SASHELP.FISH template=MYGRAPH;
run;




2015年7月10日金曜日

Graph Template Language(GTL)入門:基本構文


簡単なグラフであれば、SGPLOTプロシジャなどが使えますが、
デザインをこうしたい、ああしたい、、という場合、カスタマイズしたグラフのテンプレートを作る必要があります。

このテンプレートを作るのが、Graph Template Language(GTL)です。

出来ることが多すぎるので、ざっくり解説したいと思います。
間違ってるところなどがあれば、修正・追記していく予定ですので、ご指摘お願いします。


基本構文

①まずは、TEMPLATEプロシジャでグラフテンプレートを作ります。

PROC TEMPLATE  ;
   DEFINE STATGRAPH テンプレート名  ;
       BEGINGRAPH  ;

               ENTRYTITLE "グラフタイトル" ;
               LAYOUT レイアウト種類  ;
                      プロット文  ;
               ENDLAYOUT ;
               ENTRYFOOTNOTE "フットノート" ;

       ENDGRAPH  ;
   END  ;
RUN ;

  DEFINE STATGRAPH テンプレート名 ;
      ~
  END ;
 作成するテンプレート名を指定。
 適当な名前でok。

  BEGINGRAPH ;
      ~
  ENDGRAPH ;
 お決まりの文。開始と終了を明示。


  ENTRYTITLE "タイトル" ;

 グラフのタイトル

  ENTRYFOOTNOTE "フットノート" ;

 グラフのフットノート

  LAYOUT レイアウト種類 ;
      ~
  ENDLAYOUT ;

 複数のプロットを左右に並べたり、重ねたり、、
 等のレイアウトの種類を選択します。

 (ここは別の機会で紹介予定)


②上で作ったテンプレートを、SGRENDERプロシジャで読み込んで、グラフを作ります。

PROC SGRENDER  DATA=プロットするデータセット  TEMPLATE=テンプレート名 ;
RUN;



簡単な例

* Sample Dataset ;
data DT1;
    input DAY WEIGHT;
    cards;
0  85.5
10 79.5
20 75.2
30 70.5
40 65.8
50 72.1
;

* テンプレートを作成 ;
proc template ;
  define statgraph MYTEMP ;
     begingraph;

          entrytitle "ダイエット記録";
          layout overlay;
               seriesplot x=DAY y=WEIGHT / display=all ;
          endlayout;   

     endgraph;
  end;
run;

* テンプレートを使って、グラフを作成 ;
proc sgrender data=DT1 template=MYTEMP ;
run;




(上記「結果のグラフ出てこないよ」って場合は、なんかしらの設定によって出力がオフになっている可能性あり)


解説

基本構文と照らし合わせると理解しやすいと思います。
ただしプログラム中の以下の部分は、別記事で解説予定なので、詳細は割愛します。

layout overlay;
     seriesplot x=DAY y=WEIGHT / display=all ;
endlayout;  

ざっくりですが、
layout overlayでなんかレイアウトを設定してから、seriesplotステートメントを使って時系列にプロットをしてるって感じです。



GTL入門記事一覧