SAS

GTLとwhereステートメントの比較

GTLはwhereステートメントと同等の処理を実行できるように見えますが、実はそうではありません。

whereステートメントをGTL単体で再現できるかやってみました。

whereステートメントの使用例

再び東京都_新型コロナウイルス陽性患者の推移データを利用します。40代以上と40代未満の二つのグループに分けて患者数の時間推移をプロットします。

proc template; 
define statgraph mygraph;
dynamic _TIME _PAT _TITLE _GRP _labelx _labely;
begingraph;
entrytitle _TITLE;
   layout overlay / xaxisopts=(label=_labelx)
                    yaxisopts=(label=_labely);
      seriesplot x=_TIME y=_PAT /
         name="series"
         group=_GRP;
   discretelegend "series";
   endlayout;
endgraph;
end;
run;

proc sgrender data=ds2 template=mygraph;
dynamic _TITLE="東京都_新型コロナウイルス陽性患者"
        _TIME="DATE"
        _PAT="COUNT"
        _GRP="GROUP"
        _labelx="日付"
        _labely="患者数";
run;
実行結果1

実行結果

2020年4月15日以降のデータをプロットしたいときはsgrenderプロシジャを以下のように修正します。mdy関数は年、月、日の数値からSAS日付値を生成する関数です。

proc sgrender data=ds2 template=mygraph;
   dynamic _TITLE="東京都_新型コロナウイルス陽性患者"
           _TIME="DATE"
           _PAT="COUNT" 
           _GRP="GROUP"
           _labelx="日付"
           _labely="患者数";
   where DATE >=mdy(4,15,2020);

run;
実行結果2

実行結果

GTLのeval関数を使用した場合

同じことをwhereステートメントを使用せずにGTLのみで実現してみます。
eval関数を使うのであれば最初に以下のようなコードが思いつきますが、実際にプロットをすると日付は0と1しか表示されません。

seriesplot x=eval(_TIME>= mdy(4,15,2020)) y=_PAT / name="series" group=_GRP;

実はGTLのeval関数はwhereステートメントと異なり、データのサブセットを作りません、代わりに条件式を判定した結果を論理値(0と1)として格納した変数を新規に作成します。

上の例では4月15日以前の日付は0,、4月15日以降の日付なら1を格納した変数を作成し、それをプロットしているわけです。

特定の日付以降のデータをプロットするには以下のようにします。

seriesplot x=eval(ifn(_TIME>= mdy(4,15,2020),_TIME,.)) y=_PAT / name="series" group=_GRP;

ifn関数はexcelのif関数と同じです。条件式がtrueの時は_timeを、falseの時は欠損値を返します。欠損値はプロットされないのでこれで行ける!と思ったら・・・

実行結果3

実行結果

プロットはあっているみたいですが、X軸が日付値になっていません。eval関数で作成した変数は代入元の変数のフォーマットを引き継がないんですね。うーんめんどくさい。このテクニックを使うのならy軸の変数だけですね。こっちはフォーマット関係ないので。

まとめ

データを抽出してプロットすること自体はGTL単体でもできますが、データを事前に加工するかsgrenderとwhereステートメントを併用するほうが早いですね。わざわざGTLを使うメリットがありません。

まあGTLでデータを抽出するなんて普通やりませんがね