SAS

GTLでスイマープロットを作図する(1)highlowplotステートメント

抗がん剤研究でたまに見かけるスイマープロット。聞いたことがない方が多いですが、治療履歴を個々の患者ごとに表示するときは便利なグラフです。
今回はGTLでスイマープロットを作図する方法を紹介いたします。

スイマープロット(swimmer plot)とは

スイマープロットは各患者の治療履歴やイベント発生履歴を棒グラフや散布図のマーカーで表現したグラフです。主に個々の患者の治療と腫瘍サイズの変化を表現するのに用いられます。
縦軸は個々の被験者、横軸は治療開始からの経過時間とし、被験者は観察期間順に並べ替えるのが一般的なようです。個々の患者が一列に並んで時間経過に従い一斉に右方向へ移動していくところが競泳プールとそっくりなところからswimmer plotと呼ばれるようになったのだと思います。工数管理等で用いられるガントチャートに似ています。

SASの公式ブログではswimmer plotの作図方法が紹介されています。

初期の頃はbarchartとscatterplotの併用で作図されていましたが、時系列データの表示に適したhighlowplotステートメントを利用するほうが効率的です。

Highlowplotステートメント

highlowplot < y=item or x=item > low=low high=high/ 
   type=< bar or line > 
   group=< クラス変数 > 
   barwidth=0.9 
   display=(fill) 
   datatransparency=0.4 
   highcap=< 設定値を格納した変数 > 
   includemissinggroup=false 
   name="highlow";

Highlowplotステートメントはlowとhighで指定した範囲をラインまたは棒グラフで結びます。特定の期間を表示するのに便利です。

typeオプションでlowとhighを結ぶ図形を選択します。
barwidthは棒グラフの幅を0から1の範囲で設定します。

highcapはhigh側のキャップ図形を変更することができます。指定した変数に引数を格納しておくと特定のレコードのキャップ図形を変更することができます。
今回は継続中の患者のレコードに”Filledarrow”を格納することで、継続中の場合は矢印形状に変更しています。棒グラフの形状から継続中か否かがわかるようになっています。

includemissinggroupオプションでfalseを設定するとグループ変数に欠損値が格納されている場合そのレコードは無視されます。

作図コード

swimmer plotはGTLおよびsgplotの両方で作図可能です。公式ブログではsgplotを利用していますが、ここではGTLを使って作図してみます。GTLはattribute mapの定義をテンプレートに直接書き込むことができるのでattribute map datasetの作成は必要ありません。

proc template; 
define statgraph swimmer; 
begingraph; 

entryfootnote halign=left "Each bar represents one subject in the study. Right arroq cap indicates continued response."; 
entryfootnote halign=left "A durable responder is a subject who has confirmed response for at least 183 days (6 months)."; 

discreteattrmap name="stage" / discretelegendentrypolicy=attrmap; 
   value "Stage 1" / fillattrs=GraphData1; 
   value "Stage 2" / fillattrs=GraphData2; 
   value "Stage 3" / fillattrs=GraphData3; 
   value "Stage 4" / fillattrs=GraphData4; 
enddiscreteattrmap; 

discreteattrvar attrmap="stage" attrvar=_grp var=stage; 

discreteattrmap name="status" / discretelegendentrypolicy=attrmap; 
   value "Complete response" / lineattrs=GraphData2 fillattrs=GraphData2 markerattrs=GraphData2; 
   value "Partial response" / lineattrs=GraphData1 fillattrs=GraphData1 markerattrs=GraphData1; enddiscreteattrmap; 

discreteattrvar attrmap="status" attrvar=_grp2 var=status; 

legenditem type=marker name="start" / markerattrs=(color=grey symbol=trianglefilled size=12) label="Response start"; 

legenditem type=marker name="end" / markerattrs=(color=grey symbol=circlefilled size=12) label="Response end"; 

layout overlay/ 
   xaxisopts=(label="Months" labelattrs=(size=12) 
      linearopts=(
         tickvaluesequence=(start=0 end=18 increment=1)
      )
   ) 
   yaxisopts=(type=discrete reverse=true display=(label) 
      label="Subjects Received Study Drug" 
      labelattrs=(size=12)); 

   highlowplot y=item low=low high=high/ 
      type=bar 
      group=_grp 
      barwidth=0.9 
      display=(fill) 
      datatransparency=0.4 
      highcap=highcap 
      includemissinggroup=false
      name="highlow"; 

   highlowplot y=item low=startline high=endline / 
      type=line 
      group=_grp2 
      includemissinggroup=false 
      lineattrs=(thickness=4) 
      name="startend"; 

   scatterplot x=start y=item /
      markerattrs=(size=12 symbol=trianglefilled) 
      group=_grp2 ; 

   scatterplot x=end y=item / 
      markerattrs=(size=12 symbol=circlefilled) 
      group=_grp2; 

   scatterplot x=durable y=item / 
      markerattrs=(size=12 symbol=squarefilled color=black) 
      name="durable" 
      legendlabel="durable responder"; 

   discretelegend "highlow" / 
     title="disease stage" 
     titleattrs=(size=12) 
     valueattrs=(size=12); 

   discretelegend "startend" "start" "end" "durable" / 
     location=inside 
     autoalign=(bottomright center topright) 
     across=1 
     valueattrs=(size=10); 
endlayout; 
endgraph; 
end;
run; 

ods graphics / width=25cm height=15cm; 
proc sgrender data=swimmer template=swimmer; 
run;

実行結果

実行結果

highlowplotステートメントを2つ配置して線幅と透明度を調節することで、複数の期間を同時に表示できます。これがswimmerplotのメリットです。