SAS

SAS PlotterでRaincloud plotを作図する

「SAS Plotter」はモダンなグラフを簡単に作成できるグラフマクロパッケージです。
このページではSAS Plotter version1.3 でRaincloud plotを作成する方法を解説します。

version 1.3からインストール方法が変更になりました。詳細は以下のページをご参照ください。

SAS Plotterの使用方法「SAS Plotter」はモダンなグラフを簡単に作成できるグラフマクロパッケージです。 このページではSAS Plotter Ver...

Raincloud plotとは

Raincloud plotは密度プロット(half-violin plot), 箱ひげ図、ストリッププロットを
同時に表示する作図方法です。密度プロットはカーネル密度推定を用いて作成します。
ストリッププロットはカテゴリ軸方向に揺らぎを与えることで各マーカーが重ならないようにした散布です。

Raincloud plotだけで分布形状、記述統計量、個別データの可視化を同時に実現できます。
棒グラフ+エラーバーのような従来の可視化方法は分布形状の情報やRAWデータの情報が欠落している欠点がありますが、
Raincloud plotは多峰性の分布があっても正確に可視化できます。

Raincloud plotの詳細はMicah Allen氏の資料が参考になると思います。

Input data

key変数変数タイプ
1カテゴリ変数数値または文字列
2群変数数値または文字列
応答変数数値

群変数は任意です。群変数とカテゴリ変数は文字列型でも動作しますが、その場合はテキストの昇順でグループの表示順を決定します。
順番を定義したい場合はフォーマットを適用した数値変数を使用することを推奨します。

文法

ods graphics / < graphics option > ;
ods listing gpath=< output path >;

 %RainCloud(
              data=,
              x=,
              y=,
              group=None,
              yticks=,
              xlabel=x,
              ylabel=y,
              cat_iv=2.5,
              element_iv=0.02,
              scale=area,
              trim=True,
              connect=false,
              gridsize=401,
              bw_method=sjpi,
              bw_adjust=1,
              orient=v,
              legend=false,
              legendtitle=#,
              jitterwidth=0.1,
              outlinewidth=1,
              palette=sns,
              note=,
              deletedata=True);

パラメータ

data : データセット(必須)

入力データ。keep, rename, whereオプションを併用できます。

x : 変数(必須)

カテゴリ変数

y : 変数(必須)

応答変数

group : 変数(任意)

群変数。xオプションと同じ変数を指定すると、各グループはそれぞれ別の色で塗り分けられます。指定しない場合はすべてのオブジェクトは同じ色になります。デフォルト=None

xlabel : テキスト(任意)

カテゴリ軸のラベル。デフォルトはx変数のラベル。以下のように設定するとラベルは非表示となります。xlabel=,

ylabel : テキスト(任意)

応答変数軸のラベル。デフォルトはy変数のラベル。以下のように設定するとラベルは非表示となります。ylabel=,

yticks : リスト(必須)

応答変数軸の目盛りを指定できます。半角スペースで区切られた数値リストを指定してください。数値は昇順で指定する必要があります。(例)yticks = 10 20 30 40,

cat_iv : 数値(任意)

各カテゴリの間隔。デフォルトは2.5。

element_iv : 数値(任意)

密度プロット、箱ひげ図、ストリッププロットの間隔。デフォルトは0.02。

scale : キーワード(任意)

密度プロットの高さの調整方法を指定します。
“area”にすると密度プロットの曲線下面積はすべて同じになるように調整されます。
“width”にすると各密度プロットの高さは同じになります。
デフォルトは”area”。

trim : 真偽値(任意)

Trueに設定すると観測データの範囲外の密度は非表示となります。
デフォルトはTrue。

connect : 真偽値(任意)

Trueに設定すると箱ひげ図の平均値をグループごとに線でつなぎます。
デフォルトはFalse。

gridsize : 数値(任意)

KDEのグリッド数。デフォルトは401(proc kdeのデフォルト値)

bw_method : キーワード(任意)

KDEのバンド幅推定方法を指定します。デフォルトはsjpi(proc kdeのデフォルト値)。利用可能な推定方法は以下の通りです。

  • sjpi (Sheather-Jones plug-in)
  • snr (simple normal reference)
  • snrq (simple normal reference that uses the interquartile
    range)
  • srot (Silverman\’s rule of thumb)
  • os (oversmoothed)

bw_adjust : 数値(任意)

バンド幅のファクター。この値を大きくすると密度はより滑らかになります。デフォルトは1。

legend : 真偽値(任意)

Trueを指定すると凡例を表示します。groupオプションを”None”を指定するとこの引数は無視されます。 デフォルトはFalse。

orient : キーワード(任意)

作図の方向を指定します。v=垂直方向 h=水平方向。
デフォルトはv。平均値の推移に注目している場合はv、分布形状の比較に注目している場合はhを選択するとよいと思います。

jitterwidth : 数値(任意)

ストリッププロットの揺らぎ幅を指定します。0~1の範囲の数値を指定し、値が大きくなると揺らぎが大きくなります。
値が大きすぎると箱ひげ図と重なるかもしれません。デフォルトは0.05。

outlinewidth : 数値(任意)

密度プロットと箱ひげ図の枠線の太さを数値で指定します。
デフォルトは1。

pallete : キーワード (オプション)

塗り、ライン、マーカーのカラーパレット、以下のパレットが利用可能です。デフォルトはSNS(seabornのデフォルトパレット)

  • SAS
  • SNS (Seaborn)
  • STATA
  • TABLEAU

note : ステートメント(オプション)

グラフテンプレートにentryステートメントを挿入し、グラフタイトルまたはフットノートを表示します。デフォルトは””(表示しない)

deletedata : 真偽値(オプション)

マクロが作成した一時データを削除します。デフォルトはTrue(一時データを削除する)。

作図例

作図例はgithubのexample内にsasプログラムを格納しています。filenameステートメントを使えばすぐに実行できます。

ods listing gpath=<your output path>; 
filename exam url "https://github.com/Superman-jp/SAS_Plotter/raw/main/example/raincloud_example.sas" encoding="UTF-8"; 

%include exam;

シンプルなプロット

pythonのグラフパッケージSeabornに含まれるテストデータ「Tips」を利用して作図します。githubでテストデータが公開されていますのでこれをロードします。

filename raw url "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv";
PROC IMPORT OUT= WORK.raw
            DATAFILE= raw
            DBMS=CSV REPLACE;
   GETNAMES=YES;
   DATAROW=2;
   guessingrows=max;
RUN;

proc format;
value dayf
1="Mon"
2="Tue"
3="Wed"
4="Thu"
5="Fri"
6="Sat"
7="Sun"
;
run;
data tips;
set raw(rename=(day=day_old));
format day dayf.;
label total_bill="Total bill (USD)"
      day="day of week";

select (day_old);
   when ("Thur") day=4;
   when ("Fri") day=5;
   when("Sat") day=6;
   when("Sun") day=7;
   otherwise put "WAR" "NING: irregular string" day_old;
end;
drop day_old;
run;

まずはシンプルなプロットから、seabornのバンド幅決定アルゴリズムはsrotなのでbw_methodパラメータを変更しています。

title "simple vertical raincloud plot";
ods graphics /reset=all height=15cm width=25cm imagename="rain_simple" imagefmt=png;
%RainCloud(data=tips,
            x=day,
            y=total_bill,
            cat_iv=2.5,
            element_iv=0.5,
            group=day,
            yticks=0 20 40 60,
            bw_method=srot,
            note=%nrstr(entrytitle 'your title here';
                  entryfootnote halign=left 'your footnote here';
                  entryfootnote halign=left 'your footnote here 2';)
            );
基本的なraincloud plot(垂直方向)

orientパラメータをhにするとプロットは水平方向に変更されます。
(x軸=応答変数, y軸=カテゴリ)

基本的なraincloud plot (水平方向)

グループ毎に表示

喫煙の有無別にプロットします。

title "grouped raincloud plot";
ods graphics /reset=all height=25cm width=15cm imagename="rain_grouped" imagefmt=png;

%RainCloud(data=tips,
            x=day,
            y=total_bill,
            group=smoker,
            cat_iv=2.5,
            element_iv=0.5,
            yticks=%str(0 20 40 60),
            bw_method=srot,
            orient=h,
            legend=True
            );
群別reaincloud plot

平均値をラインで結ぶ場合はconnectパラメータをTrueにしてください。

コード

ods graphics /reset=all height=15cm width=25cm imagename="rain_grouped_connect" imagefmt=png;

%RainCloud(data=tips,
            x=day,
            y=total_bill,
            group=smoker,
            cat_iv=2.5,
            element_iv=0.5,
            yticks=%str(0 20 40 60),
            bw_method=srot,
            orient=v,
            connect=true,
            legend=True
            );
平均値を線でつなぐ

Trim パラメータ

TrimパラメータをFalseに設定すると、密度プロットはすべての範囲で表示されます。
ただし観測データの範囲外の密度はあまり正確ではない点には注意してください。

title "raincloud plot with trim parameter";
ods graphics /reset=all height=25cm width=15cm imagename="rain_trim" imagefmt=png;

%RainCloud(data=tips,
            x=day,
            y=total_bill,
            group=smoker,
            cat_iv=2.5,
            element_iv=0.5,
            yticks=-20 0 20 40 60,
            bw_method=srot,
            trim=false,
            orient=h,
            legend=True
            );
観測範囲外の密度を表示 (trim=False)

Scale パラメータ

scaleパラメータを”area”に指定すると、すべての密度プロットの曲線下面積は同じになるように設定されます。
以下の例ではscale=areaに設定してirisデータセットを可視化しています。

vesiocolorとverginicaは幅広の分布を示しているため、分布のピークが小さく表示されます。

コード

title "raincloud plot with scale parameter (area)";
ods graphics /reset=all height=15cm width=25cm imagename="rain_area" imagefmt=png;

%RainCloud(data=sashelp.iris,
   x=species,
   y=petalwidth,
   group=species,
   xlabel=Species,
   ylabel=Petal Width (cm),
   yticks=0 10 20 30 40,
   cat_iv=1.5,
   orient=h,
   element_iv=0.3,
   trim=false,
   scale=area,
   bw_method=srot
   );
scale=area (デフォルト)

scaleパラメータを”width”にすると、すべての密度プロットの最大値が同じ高さになるように設定されます。
先ほどの作図でscale=”width”に設定し再出力すると以下のようになります。

vesiocolorとverginicaは拡大され分布のピークが視認しやすくなります。

title "raincloud plot with scale parameter (width)";
ods graphics /reset=all height=15cm width=25cm imagename="rain_width" imagefmt=png;

%RainCloud(data=sashelp.iris,
            x=species,
            y=petalwidth,
            group=species,
            xlabel=Species,
            ylabel=Petal Width (cm),
            yticks=0 10 20 30 40,
            cat_iv=1.5,
            orient=h,
            element_iv=0.3,
            trim=false,
            scale=width,
            bw_method=srot
            );
scale=width

KDEを用いた密度プロットは定量的ではない点には注意が必要です。基本的に分布の形状および同条件で推定したグループ間の相対的な比較以外には利用できないと考えたほうが良いでしょう。

さらにwidthを指定した場合は相対的な比較もできなくなります。分布形状に関する情報にしか興味はなく、各グループの分布形状が大きく異なる場合はwidthを利用したほうが便利なケースもあるでしょう。