Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
SASプログラムの可視化 - SASプログラムステップフローチャート
生成プログラムの紹介 - ○福田 裕章1
(1MSD株式会社)
Visualization of SAS programs Hiroaki Fukuda
MSD K.K.
要旨: データステップ及びSGPLOTプロシジャにおけるPOLYGON/TEXTステートメントを利用したSASプログラムステップフローチャートを生成するSASプログラムを紹介する。
キーワード:SGPLOT, フローチャート, 可視化
2
背景
データ加工
Proc Step
Proc Step
データ加工
...
一般的なSASプログラム
SASプログラムをSASプログラムで読み込み処理することで、 プログラムのステップフローチャートを作成する
フローの可視化が望ましい
様々なデータハンドリング
技術 Hash
Object
Proc DS2
Proc Lua
主流は基本的なData StepやSQLプロシジャ ⇒ハンドリングのために数多のステップが発生
プログラムの把握に一苦労
フローチャート化
Data Step
Proc SQL
3
SASプログラムの判定
• 例:データステップの開始
「data」で始まっている 「data」の直前が「*/」や「;」で終了している 「data」に続けて空白+データセット名可能文字列が記載 などなど
4
SASシステムによる認識判定
SASプログラムによる プログラムステップ判定
• data, proc, set, mergeなどのステートメントに対する処理 • コメントアウトやクオーテーションの処理 • 他にも様々な条件や記載方法(改行等)の考慮
≒
柔軟なテキスト操作やデータハンドリングが必要
プログラムの概要
• SASプログラムの読み込み • コメント・クオーテーションの処理 • 各種ステートメントの処理
Data Statement Proc Statement Set Statement Merge Statement SQLの処理
• フローの分岐処理 Grouping処理 = X座標の決定 出力対象とするTextの選択 Y座標の決定
• アウトプット(Box/Arrow)用のDataset作成 • フローチャートの描画
5
コード処理
分岐処理
アウトプット処理
Perl Regular Expressionを利用
Hash Objectを利用
SGPLOT プロシジャを利用
(座標処理)
テキスト操作の柔軟性 – Perl Regular Expression
• Perl正規表現の一部をSASでは関数として使用することが可能 ⇒パターンマッチにより、複雑な文字処理が可能
6
コメントアウトの処理(一部) * rec2: プログラムコード格納変数;
<prxchange関数> (perl-regular-expression, times, source) * 引数の1番目がPerl正規表現で特定の文字列パターンを置換
*** 先頭行や前行の最後が「;」「*/」で終了している場合; rec2 = prxchange('s/(%¥*.*?;|¥/¥*.*?¥*¥/|(^|(?<=[^¥w_¥))) *?¥*.*?;)//', -1, rec2); *** 改行により複数行にまたがっている場合(/* */); if index(rec2, "/*") then do; asts1fn = 1; cont1fn = 1; rec2 = prxchange('s/¥/¥*.*?//', 1, rec2); end; if index(rec2, "*/") then aste1fn = 1; if cont1fn = 1 then do; if aste1fn ^= 1 then rec2 = ""; else if aste1fn = 1 then do; rec2 = prxchange('s/(^.*?¥*¥/)//', 1, rec2); cont1fn = 0; end; end;
テキスト操作の柔軟性 – Perl Regular Expression
7
データステップの処理(一部:条件分岐の提示のみ) *** 以下のパターンに場合分けしてフラグを設定 ; ** 1.data statementが一行内で完結している場合; prxmatch('m/;( *)data( +)([¥w_])+(.*);/i', rec2) ** 2.前行の最後が「;」「*/」で終了している場合; prxmatch('m/(;|¥*¥/)$/', trim(pre_line2)) * 2-1.「data 」で終了している場合(継続); prxmatch('m/^data( *)$/i', trim(rec2)) * 2-2.「data 」が存在する場合(継続); prxmatch('m/^data( *)/i', rec2) * 2-3.一行内で完結している場合; prxmatch('m/^data( +)([¥w_])+(.*);/i', rec2) ** 3.先頭行の場合; * 3-1.「data 」で終了している場合(継続); prxmatch('m/^data( *)$/i', trim(rec2)) * 3-2.「data 」+データセット名等で終了している場合(継続); prxmatch('m/^data( +)([¥w_])+(.*)/i', rec2) * 3-3.一行内で完結している場合; prxmatch('m/^data( +)([¥w_])+(.*);/i', rec2) ** 4.その他の場合; ...
<prxmatch関数> (perl-regular-expression, source) * 引数の1番目がPerl正規表現で、特定の文字列パターンに該当するかを判定
各パターンを考慮することで、データステップの開始かどうかを判定
データハンドリングの柔軟性 – Hash Object
A
B
C
D
E
Q
O P
X
Y
① ② ③
④
X座標の決定:①~④ • 最終ステップを含むグループを支点と
して決定 • フローの上流から分岐を決定 • Input/Outputの関係から、どの分岐先
に属するか判定(下プログラム)
Y座標の決定:(1)~(11) • 下流(最終ステップ)から上流へ決定 • 分岐がある場合に複数のInputが同座
標になるように決定
X座標の決定方向
Y座標の決定方向
(1)
(2)
(3)
(4)
(5)
(7)
(9) (10)
(8)
(11)
8
*** X座標(group)の決定; dcl hash itxtlst(); itxtlst.definekey('itext'); itxtlst.definedata('group'); itxtlst.definedone(); rc1 = itxtlst.check(key: text); ** Object itxtlistに出力テキスト(text)が存在するか確認; if rc1 = 0 then rc2 = itxtlst.find(key: text); ** itxtlistに存在すれば、groupを取得; if group ^= . and (istepseq <= 2) then igroup = group; if igroup > &i. then rc3 = itxtlst.add(key: itext, data: igroup); ** Inputの情報をHashに格納;
フローチャートの作成
• SAS9.4からSGPLOTプロシジャにPOLYGON/TEXTステートメントが追加された
ods graphics / imagemap=on; ** TIPオプション使用に必須; proc sgplot data=output noborder noautolegend; ** POLYGONステートメントによるボックスの描画; polygon id=boxid x=box_x y=box_y; ** TEXTステートメントによるテキストの描画; text x=text_x y=text_y text=text / textattrs=(size=5) splitchar='.' splitpolicy=splitalways tip = (code); ** SERIESステートメントによる矢印の描画; series x=arrow_x y=arrow_y / group=arrowid lineattrs=(color=black) arrowheadpos=end arrowheadscale=0.2; ** 軸の設定; xaxis display=none min=&xmin. max=&xmax. offsetmin=0 offsetmax=0; yaxis display=none min=&ymin. max=&ymax. offsetmin=0 offsetmax=0; run;
Textを囲う枠線を定義するデータセットBox由来の変数:頂点の座標を定義
矢印を定義するデータセットArrow由来の変数:始点・終点の座標を定義
9
結果1 – 単純なプログラムの場合
10
☆TIPオプションにより指定した変数の値を表示できる ⇒各ステップのコードを表示するように設定
** Create Data A; data A; set sashelp.class; run; proc sort data = A; by name age; run; ** Create Data B by SQL procedure; proc sql; create table B as select X.*, Y.pop from X inner join (select * from sashelp.demographics) as Y on X.COUNTRY = Y.ISONAME; quit; proc sort data = B out = B; by name age; run; ** Create Data C from A and B; data C; merge A (in = in1) B (in = in2); by name age; if in1 = in2; run; proc print data = C noobs; run;
データC生成のコードを表示
結果2 – 実際の解析データセット作成プログラムに適用した場合
11
まとめ • 簡単な解析データセット作成プログラムならば、フローチャー
トの作成が可能であった。 • ステップが増大すると、作図の都合上、図形が小さくなるの
で、分割などを考慮する必要がある。 • マクロ処理やMerge処理が十分ではないので、こうしたス
テップへの対応が今後の課題である。
プロシジャの場合、枠の形状が「◇」になるように調整
例:AEの解析データセット作成プログラム
参考
• SAS 9.4コンポーネントオブジェクト: リファレンス 第2版http://www.sas.com/offices/asiapacific/japan/service/help/pdf/v94/lecompobjref.pdf
• SAS 9.4 関数とCALLルーチン:リファレンス 第4版http://www.sas.com/offices/asiapacific/japan/tools/download.html?url=http://support.sas.com/documentation/cdl_alternate/ja/lefunctionsref/67960/PDF/default/lefunctionsref.pdf
• Steven First (2016) “Innovative Performance Improvements Through Automated Flowcharts In SAS” SAS Global Forum 2016.
12