データの分布を可視化するときはヒストグラムをよく使います。特にデータの分布が正規分布に従うかどうかを直感的に判断したいときは便利です。
GTLでヒストグラムを作図するときはhistgramステートメントかhistgramparmステートメントを使用します。
histgramステートメント
histgramステートメントは作図したい変数を指定するだけですぐにヒストグラムを作成してくれます。
それに対しhistgramparmステートメントの場合は、あらかじめ算出したビンの中心点および頻度またはパーセントを格納した変数を指定する必要があります。このビンの中心を格納した変数はあらかじめソートしなければなりません。当然ですが頻度あるいはパーセントを格納した変数は負の値を格納することはできません。
ビンの設定はデータの範囲とオブザベーション数から自動で設定されますので、ビンの設定を定義しなくてもOKです。
縦軸の値はデフォルトはパーセントですが、頻度や密度を指定することも可能です。
試しにsashelpのデータセットを使って新生児の体重の分布を作図してみます。
proc template;
define statgraph hist;
begingraph;
layout overlay;
histogram weight;
endlayout;
endgraph;
end;
run;
proc sgrender data=sashelp.bweight template=hist;
run;
ビンの設定
次にビンの設定を追加してみます。histgramparmステートメントではビンの設定はできません。
ビンの設定 | 説明 |
---|---|
BINSTART | 最初のビンの中心点を定義する |
BINWIDTH | ビンの幅を定義する |
NBINS | ビンの個数を定義する |
proc template;
define statgraph hist;
begingraph;
layout overlay;
histogram weight /
binstart=200
binwidth=100;
endlayout;
endgraph;
end;
run;
応答変数の設定
応答変数(縦軸の変数)は特に設定しない場合パーセントとなりますが、頻度や密度に指定することができます。
変更する場合はscaleオプションをpercent, countあるいはpropotion(比率)のいずれかを指定します。まあどれを選んでもヒストグラムの形状は変わりませんが。
グループの設定
groupオプションを設定すると指定したクラス変数ごとにヒストグラムを作成します。
先ほどのヒストグラムを男女に分けて出力してみましょう。boyという変数は男子の場合1が格納されるのでこれを利用します。
この時ビン同士が重なってしまいわかりにくくなる場合は、透過度や塗りつぶしの設定を変えて見やすくしたほうがいいです。
proc template;
define statgraph hist;
begingraph;
layout overlay;
histogram weight /
binstart=200
binwidth=100
group=boy
fillattrs=(transparency=0.5)
filltype=ALPHAGRADIENT
name="hist" ;
discretelegend "hist";
endlayout;
endgraph;
end;
run;
若干男子のほうが重いですが、性別差はほとんどないとみてよさそうですね。
mirrored histogramの作成
前項ではクラス変数ごとにヒストグラムを作成しましたが、これだと2つの群が重なってしまいあまり見やすくありません。この場合はmirrored histogramを検討したほうが良いでしょう。
mirrored histogramは片方の群を度数(または密度)=0を境にして上下反転させることで群同士を重ならないように工夫したヒストグラムです。臨床試験分野ですと2群の傾向スコアの分布を可視化するときに用いられることがあります。
mirrored histogramはSASのオプションで作成することができません。layout latticeを併用する方法と度数をマイナスに反転させる方法の2通りがありますが、レイアウトの柔軟性を考えると後者のほうが利便性が高いと思います。
今回は2群の傾向スコアを2通りの方法でヒストグラムにしてみます。処理群とコントロール群の傾向スコアの分布をmirrored histogramとして表示します。ビン幅は0.05刻みに設定します。
layout lattice の使う方法
こちらはプロットエリアを2分割し、各群のヒストグラムを作図します。各群ごとに傾向スコアの変数を用意しなくてもeval関数をifn関数の併用することで特定の群のデータのみを表示させることが可能です。
下のヒストグラムはY軸を反転(reverse=True)とすることで上下反転させることができます。
histogramステートメントのbinaxisオプションをfalseにすると軸目盛に依存せずに任意のビンを設定できます。Trueだと目盛りに基づいてビンが設定されます。
この方法のメリットは別途ヒストグラムの集計をしなくてもプロットステートメントだけで直接作図できる点ですが、密度=0の部分に空白ができてしまいます。これはY軸の目盛りの値を表示するスペースを確保するためのものなので上下のプロットエリアをぴったりくっつけることはできません。
/*データセットps trt=群変数(0=control, 1=treated) ps=傾向スコア*/
proc template;
define statgraph mirror1;
begingraph; /*塗りつぶしの設定*/
discreteattrmap name="_map" / discretelegendentrypolicy=attrmap;
value "Control" / fillattrs=GraphData1;
value "Treated" / fillattrs=GraphData2;
enddiscreteattrmap;
discreteattrvar var=trt attrvar=_grp attrmap="_map";
layout lattice / rows=2 columndatarange=union rowgutter=0;
/*列の軸設定*/
columnaxes;
columnaxis / offsetmin=0.02 offsetmax=0.02
label="Propencity Score"
linearopts=(
viewmin=0 viewmax=1
tickvaluesequence=(start=0 end=1 increment=0.1)
);
endcolumnaxes;
/*処理群*/
layout overlay /
yaxisopts=(display=(line ticks tickvalues)
linearopts=(
viewmin=0 viewmax=0.2
tickvaluesequence=(
start=0 end=0.2 increment=0.05)
)
);
histogram eval(ifn(trt=1, ps,.)) /
binstart=0.025
binwidth=0.05
group=_grp
scale=proportion
binaxis=false
name="hist";
endlayout;
/*コントロール群*/
layout overlay /
yaxisopts=(display=(line ticks tickvalues)
reverse=true
linearopts=(
viewmin=0 viewmax=0.2
tickvaluesequence=(
start=0 end=0.2 increment=0.05)
)
);
histogram eval(ifn(trt=0, ps,.)) /
binstart=0.025
binwidth=0.05
group=_grp
scale=proportion
binaxis=false;
endlayout;
/*共通軸ラベル*/
sidebar / align=left spacefill=false;
entry "Density" /
rotate=90
textattrs=(size=10) pad=10;
endsidebar;
/*凡例*/
sidebar / align=bottom spacefill=false;
discretelegend "hist" /
displayclipped=true ;
endsidebar;
endlayout;
endgraph;
end;
run;
proc sgrender data=ps template=mirror1;
run;
barchartparamを使う方法
もう一つの方法はあらかじめヒストグラムデータセットを作成し、棒グラフとして作図する方法です。集計データセットの密度をマイナスに反転させることで
上下反転したヒストグラムを作成することができます。データセットを加工してマイナスに反転させるのも良いですが、eval関数とifn関数を併用することで
作図のために必要な変数加工をGTL上で実行することができます。
このままだとY軸の目盛りがマイナスとなってしまいますが、pictureフォーマットを利用することで先頭のマイナス表示を非表示にしています。
この方法ですと体裁の調整の自由度が高いのでお勧めです。なお傾向スコアの分布のFigureはだいたいこの形で発表されているようです。
/*軸目盛からマイナス表記を取り除く*/
proc format;
picture axis(round default=10)
low-high="9.99";
run;
/*ヒストグラムデータセットを作成*/
ods output histogram=hist;
proc univariate data=ps noprint ;
histogram ps /
midpoints=(0.025 to 0.975 by 0.05)
vscale=proportion;
by trt;
run;
proc template;
define statgraph mirror2;
begingraph;
layout overlay /
xaxisopts=(
type=linear
label="Propencity Score"
linearopts=(
viewmin=0 viewmax=1
tickvaluesequence=(
start=0 end=1 increment=0.1)
)
)
yaxisopts=(
type=linear
label="Density"
linearopts=(
tickvalueformat=axis.
viewmin=-0.2 viewmax=0.2
tickvaluesequence=(
start=-0.2 end=0.2 increment=0.05)
)
);
barchartparm category=BinX response=eval(ifn(trt=0,-Bincount,Bincount)) /
barwidth=1
group=trt
name="hist";
discretelegend "hist";
endlayout;
endgraph;
end;
run;
proc sgrender data=hist template=mirror2;
run;
なおグラフパッケージ「SAS Plotter」でも作成できます。
https://picolabs.jp/sasplotter_mirrored_histogram/