SAS

GTLの軸設定を極める(3) ラベルと目盛線の設定方法

軸設定の解説の3回目はラベルと目盛線の制御です。

目盛りラベルは特になにも設定しない場合は軸変数のフォーマットを使用します。ラベルの体裁の制御やSASが強制的にフォーマットを設定するような場合はGTL上で設定する必要があります。

目盛りラベルに任意のフォーマットを適用する

目盛りラベルにフォーマットを適用するためにはtickvalueformatオプションを使用します。このオプションはすべての軸タイプで使用可能です。

今回は以下のようなデータとフォーマットを用意し、棒グラフを作成してみます。

proc format; 
   value visit 1="Visit 3 (1期ベースライン)" 
               2="Visit 9 (1期最終評価時点)" 
               3="Visit 12 (2期ベースライン)" 
               4="Visit 18 (2期最終評価時点)" ; 
run; 

data test; 
length avisit $50; 
avisitn=1; 
avisit="Visit 3 (1期ベースライン)"; 
aval=30.5;
output; 

avisitn=2; 
avisit="Visit 9 (1期最終評価時点)"; 
aval=25.5;
output; 

avisitn=3; 
avisit="Visit 12 (2期ベースライン)"; 
aval=28.8;
output; 

avisitn=4; 
avisit="Visit 18 (2期最終評価時点)"; 
aval=21.5;
output; 
run;

tickvalueformatオプションを利用してVisitのコード値AVISITNにフォーマットを適用して棒グラフを作成します。

proc template; 
define statgraph label; 
begingraph; 

layout overlay / 
   xaxisopts=(type=linear linearopts=(tickvalueformat=visit. tickvaluelist=(1 2 3 4)) ); 

   barchartparm category=avisitn response=aval/ 
      barwidth=0.5; 
endlayout; 
endgraph; 
end; 
run; 

proc sgrender data=test template=label; 
run;
実行結果

今回の場合はデータセットにあらかじめフォーマットを適用するかsgrenderプロシジャのformatステートメントを利用する方法でも同じことができますが、
GTLで仕様として強制的にフォーマットが適用されるケースがあります。その場合はtickvalueformatが必要すると任意のフォーマットを適用できます。

tickvalueformatは特定のラベルのみ表示させたい場合にも有効です。proc formatで表示したいラベルの設定を定義し、それ以外は半角スペースを表示するように
設定すると、任意のラベルのみ表示できます。以下の例では等間隔に設定した目盛りのうち特定の値のみを表示するように設定しています。

proc format; 
*非表示にする目盛りラベルは半角スペースにする; 

picture tick 0="9" 
            12="99" 
            24="99" 
            36="99" 
            52="99" 
            64="99" 
            76="99" 
            other=" "; 
run; 

proc template; 
define statgraph uneven_ticklabel; 
dynamic _atrisk_title; 

begingraph; 
layout overlay /xaxisopts=( linearopts=(viewmax=76 viewmin=0 
                   tickvaluesequence=(start=0 end=76 increment=4) tickvalueformat=tick.) ); 

   seriesplot x=ATPT y=CHG / 
      group=TRT1A 
      display=all 
      name="series" 
      yerrorlower=lower 
      yerrorupper=upper; 

   discretelegend "series" / 
      across=1 
      location=inside 
      autoalign=(bottomleft topright); 
endlayout; 
endgraph; 
end; 
run; 

proc sgrender data=import template=uneven_ticklabel; 
run;
実行結果

目盛りラベルを改行する

軸ラベルが長すぎるとデフォルトでは目盛りの一部が非表示になります。これを回避するには目盛りラベルの表示設定を変更するか、axislegendステートメントで目盛りラベルを凡例として表示する方法が考えられます。今回は目盛りラベルを改行することで非表示を回避する方法を利用してみます。

目盛りラベルの改行は離散軸のみ利用可能です。まず軸変数となる変数に改行位置を示す改行文字をあらかじめ挿入し、tickvaluesplitcharオプションでその文字を指定します。この時tickvaluefitpolicyオプションをsplitalwaysに設定することで必ず改行されるようになります。指定しない場合は目盛りラベルの表示スペースが小さい場合のみ改行されます。

今回は改行文字として「/」をAVISITに挿入しておき、必ず目盛りラベルが改行されるように設定します。

デフォルトでは半角スペースが改行文字として設定されているのですが、すべての半角スペースが改行されてしまうので改行文字を指定したほうが意図しない改行を防ぐことができます。

通常は改行文字は目盛りから取り除かれますが、tickvaluesplitchardropをfalseに設定すると改行文字も目盛りラベルに表示されます。

data test; 
length avisit $50; 
format avisitn visit.; 
avisitn=1; 
avisit="Visit 3/ (1期ベースライン)"; 
aval=30.5;
output; 

avisitn=2; 
avisit="Visit 9/ (1期最終評価時点)"; 
aval=25.5;
output; 

avisitn=3; 
avisit="Visit 12/ (2期ベースライン)"; 
aval=28.8;
output; 

avisitn=4; 
avisit="Visit 18/ (2期最終評価時点)"; 
aval=21.5;
output; 
run; p

roc template; 
define statgraph label; 
begingraph; 
layout overlay / xaxisopts=(type=discrete 
                 discreteopts=( tickvaluefitpolicy=splitalways tickvaluesplitchar="/" 
                 tickvaluesplitchardrop=true ) ); 

   barchartparm category=avisit response=aval/ 
      barwidth=0.5; 
endlayout; 
endgraph; 
end; 
run; 

ods graphics / reset=all; 
proc sgrender data=test template=label; 
run;
目盛りラベルを開業する

なおあらかじめフォーマットを適用した数値変数AVISITNを軸変数として指定した場合、フォーマット適用後の文字列に改行文字を含まれていればこのオプションは動作します。
上記のコードの場合軸変数をAVISITの代わりにAVISITNを利用してもあらかじめデータセットにフォーマットを適用しておけば同じ結果が得られます。

ただしデータセットではなくtickvalueformatオプションでAVISITNにフォーマットを適用した場合はエラーとなります。

これは離散軸に指定した場合、軸変数は最初に文字列変数(フォーマットがある場合はフォーマット適用後の文字列)として解釈されるので、文字列変数と解釈された後ではフォーマットを適用できないためです。

ちなみに軸ラベル(軸の隣に表示される文字列、通常は変数の名前かラベルが表示される)も同様にticklabelsplitcharオプションを使うことで改行位置を指定することができますが、まああまり使わないかな。

目盛りラベルの傾きを変更する

目盛りラベルの改行は、線形軸や時間軸では設定できません。

これらの軸の場合であってもデフォルトでは目盛りラベルの表示スペースが足りない場合は目盛りの一部が間引かれます。これはログにも表示されます。
これを防止するには目盛りラベルを斜めに傾けて表示する方法が利用できます。

tickvaluefitpolicyオプションでrotatealwaysを指定すると必ず目盛りラベルは斜めに配置されます。この角度はtickvaluerotationオプションで指定できます。

/* diagonal: 45度       
diagonal2: -45度 
vertical: 90度
*/

proc template; 
define statgraph label; 
begingraph; 
layout overlay / xaxisopts=(type=linear linearopts=( tickvaluelist=(1 2 3 4) 
   tickvaluefitpolicy=rotatealways tickvaluerotation=diagonal2)  ); 

   barchartparm category=avisitn response=aval/
      barwidth=0.5; 
endlayout; 
endgraph; 
end; 
run; 

ods graphics / reset=all;
proc sgrender data=test template=label; 
run;
ラベルを傾ける

目盛線を追加する

主目盛線を追加するにはgriddisplayオプションをonにし、gridattrsオプションで線の体裁を指定することで実現できます。
補助目盛線の設定は各軸オプション(discreteopts, linearopts, logopts, timeopts)の中で指定する点は注意が必要です。

主目盛線と同様にminorgriddisplayオプションをTrueに設定し、minorgridattrsオプションで線の体裁を指定すればOKです。

driddisplayのオプションはauto_on とauto_offという設定値もありますが、これは自動的に目盛線の表示を制御するものです。
同じ体裁のグラフを一つのテンプレートで作りたい場合は目盛り線の表示は明示したほうが良いです。

以下の例は主目盛を4半期、補助目盛線を月に設定しています。見やすくするため目盛線は若干太めに設定しました。

data test; 
call streaminit(123); 
format date yymmdd10.; 
do date=mdy(1,1,2021) to mdy(12,31,2021); 
result=abs(int(rand("normal")*1000))*0.1*date/100; 
output; 
end; 
run; 

proc template ; 
define statgraph axis; 
begingraph; 
layout overlay / xaxisopts=(type=time griddisplay=on gridattrs=(thickness=2 color=black pattern=solid) 
                 timeopts=( interval=quarter 
                 minortickinterval=month 
                 minorgrid=true 
                 minorgridattrs=(thickness=2 color=red pattern=shortdash)));

   seriesplot x=date y=result / 
      datatransparency=0.5; 
   endlayout; 
endgraph; 
end; 
run; 

ods graphics / height=16cm width=25cm; 
proc sgrender data=test template=axis; 
run;
補助目盛線の追加