421 Views
March 26, 24
スライド概要
[第9回大阪SAS勉強会] 増村 一穂
SAS言語を中心として,解析業務担当者・プログラマなのコミュニティを活性化したいです
多岐に渡る要望パターン とそれに対する設計 (マクロをどう組むか) 大阪大学医学部附属病院 増村 一穂
目次 ● 背景 ● マクロ作成の問題点と対策 ● まとめ
背景 ●●試験の統計解析結果の設計、作成をお願いいたします この試験は探索研究なので解析結果を見て、医師の先生と 色々な考察を考えます 統計家の先生 了解しました 私
背景:初回結果作成 対象検査値A1~A3,B1~B3の 統計量の表と箱ひげ図を Excelに出力して下さい 次のようなイメージです
背景:初回結果作成 対象検査値A1~A3,B1~B3の 統計量の表と箱ひげ図をExcelに出力 ・統計量を算出して表に出力できる形式に変換する ・箱ひげ図(3時点)を作成し、出力する の2構成のマクロを作成して引数に変数とラベル名 を指定すれば良さそう %macro BOX_LIST_RESULT(ITEM =, YLABEL=) ① 対象変数の統計量を算出(proc means) ② 表示形式(例:平均(標準偏差)→(99.9 , 99.9))に加工 ③を3時点分実行して結果を結合 ④ テンプレート1の指定箇所R6C3:R8:C6に出力する(出力はExcel ddeを使用) ⑤ 対象変数の箱ひげ図(3個)をR11C2に出力 proc sgplot data=Data1 noautolegend; vbox &ITEM / category=VISIT name="vbox"; xaxis label="時点" display=(nolabel) values=(1 to 3 by 1) valueattrs=(size=16); yaxis label=&YLABEL labelattrs=(size=16) valueattrs=(size=16); run; %BOX_LIST_RESULT(ITEM = %BOX_LIST_RESULT(ITEM = %BOX_LIST_RESULT(ITEM = %BOX_LIST_RESULT(ITEM = %BOX_LIST_RESULT(ITEM = %BOX_LIST_RESULT(ITEM = A1, A2, A3, B1, B2, B3, YLABEL="A1"); YLABEL="A2"); YLABEL="A3"); YLABEL="B1"); YLABEL="B2"); YLABEL="B3");
背景:追加要望1 作成して頂いた結果より追加要望がありました。 対象変数C1~C3、D1~D3に対してA、Bと同様に 統計量の表と箱ひげ図を作成して下さい ただしCとDはA、Bとは異なりそれぞれ時点が4、5あります ので表構成、箱ひげ図は時点に合わせたものとして下さい
背景:追加要望1 %macro BOX_LIST_RESULT2(ITEM =, YLABEL=) 対象検査値C1~C3,D1~D3の 統計量の表と箱ひげ図をExcelに出力 (Cは時点が4つ、Dは時点が5つ存在する) ① 対象変数の統計量を算出 ② 表示形式に加工 ③を4時点分実行して結果を結合 ④ テンプレート2の指定箇所R6C3:R9:C6に出力する(出力はExcel ddeを使用) ⑤ 対象変数の箱ひげ図(4個)をR12C2に出力 proc sgplot data=Data1 noautolegend; vbox &ITEM / category=VISIT name="vbox"; xaxis label="時点" display=(nolabel) values=(1 to 4 by 1) valueattrs=(size=16); yaxis label=&YLABEL labelattrs=(size=16) valueattrs=(size=16); run; %macro BOX_LIST_RESULT3(ITEM =, YLABEL=) 前に作ったマクロを使いまわそうと思ったけど テンプレート、出力範囲、箱ひげ図の設定が違う から使えないなぁ マクロ引数で指定して可変に出来そうだけど マクロ修正すると前の結果に影響が出てしまうから コピペして似たようなマクロを作って対応しよう ① 対象変数の統計量を算出 ② 表示形式に加工 ③を5時点分実行して結果を結合 ④ テンプレート3の指定箇所R6C3:R10:C6に出力する(出力はExcel ddeを使用) ⑤ 対象変数の箱ひげ図(5個)をR13C2に出力 proc sgplot data=Data1 noautolegend; vbox &ITEM / category=VISIT name="vbox"; xaxis label="時点" display=(nolabel) values=(1 to 5 by 1) valueattrs=(size=16); yaxis label=&YLABEL labelattrs=(size=16) valueattrs=(size=16); run;
背景:追加要望2 すいません。これまで作成した図表の内容に関して大幅な追加要望がありました 1 箱ひげ図の平均値に線を引く 2 脚注と図に単位を書く(A、B、C、Dは全て単位が異なる)。脚注の分だけ出力位置はずらす 3 表の表示桁数はA、Dは小数点3桁、B、Cは小数点2桁にする 4 これまで作成した図表に関して群分け(XXX群、YYY群)された集団で実施する。 箱ひげ図は縦に並べること
背景:追加要望2 %macro BOX_LIST_RESULT1(ITEM =, YLABEL=, FORMAT=, UNIT=) 1 2 3 4 ① 対象変数の統計量を算出 ② 表示形式に加工(結果の桁数(FORMAT)を指定する) ③を3時点分実行して結果を結合 ④ テンプレート1の指定箇所R6C3:R9:C6に出力する(出力はExcel ddeを使用) R9:C2に単位(UNIT)を出力 ⑤ 対象変数の箱ひげ図(3個)をR12C2に出力 箱ひげ図の平均値に線を引く 脚注と図に単位を書く 表の表示桁数を変更 群分けされた集団で作成 proc sgplot data=Data1 noautolegend; vbox &ITEM / category=VISIT name="vbox“ connect=mean; xaxis label="時点" display=(nolabel) values=(1 to 3 by 1) valueattrs=(size=16); yaxis label=&YLABEL labelattrs=(size=16) valueattrs=(size=16); run; マクロをまとめておけば良かった・・・ 1→⑤に追記 2→④⑤の間に出力処理と⑤の出力位置を修正 3→②を修正 これを今まで作った3つのマクロ全部に対応させない といけないな 4は箱ひげ図の構成が全く異なるしこれまで作った マクロを参考に新規マクロを3つ作って対応しよう %macro BOX_LIST_RESULT2(ITEM =, YLABEL=, FORMAT=, UNIT=) 上記と同様の修正 %macro BOX_LIST_RESULT3(ITEM =, YLABEL=, FORMAT=, UNIT=) 上記と同様の修正 %macro BOX_LIST_GROUP_RESULT %macro BOX_LIST_GROUP_RESULT2 %macro BOX_LIST_GROUP_RESULT3
背景:追加要望2 結果として 同じようなマクロが6個も出来てしまった 呼び出し処理もかなり増えてしまった 今回はなんとか作れたけど段々混乱してき たし、また修正があったら修正漏れしそう な構成になってしまった・・ %macro BOX_LIST_RESULT(ITEM =, YLABEL=, FORMAT=, UNIT=) %macro BOX_LIST_RESULT2(ITEM =, YLABEL=, FORMAT=, UNIT=) %macro BOX_LIST_RESULT3(ITEM =, YLABEL=, FORMAT=, UNIT=) %macro BOX_LIST_GROUP_RESULT(ITEM =, YLABEL=, FORMAT=, UNIT=) %macro BOX_LIST_GROUP_RESULT2(ITEM =, YLABEL=, FORMAT=, UNIT=) %macro BOX_LIST_GROUP_RESULT3(ITEM =, YLABEL=, FORMAT=, UNIT=) * 解析対象集団全体の処理; %BOX_LIST_RESULT(ITEM = A1, YLABEL="A1", FORMAT=8.3, UNIT=単位A1); %BOX_LIST_RESULT(ITEM = A2, YLABEL="A2", FORMAT=8.3, UNIT=単位A2); %BOX_LIST_RESULT(ITEM = A3, YLABEL="A3", FORMAT=8.3, UNIT=単位A3); %BOX_LIST_RESULT(ITEM = B1, YLABEL="B1", FORMAT=8.2, UNIT=単位B1); %BOX_LIST_RESULT(ITEM = B2, YLABEL="B2", FORMAT=8.2, UNIT=単位B2); %BOX_LIST_RESULT(ITEM = B3, YLABEL="B3", FORMAT=8.2, UNIT=単位B3); %BOX_LIST_RESULT2(ITEM = C1, YLABEL="C1", FORMAT=8.2, UNIT=単位C1); %BOX_LIST_RESULT2(ITEM = C2, YLABEL="C2", FORMAT=8.2, UNIT=単位C2); %BOX_LIST_RESULT2(ITEM = C3, YLABEL="C3", FORMAT=8.2, UNIT=単位C3); %BOX_LIST_RESULT3(ITEM = D1, YLABEL="D1", FORMAT=8.3, UNIT=単位D1); %BOX_LIST_RESULT3(ITEM = D2, YLABEL="D2", FORMAT=8.3, UNIT=単位D2); %BOX_LIST_RESULT3(ITEM = D2, YLABEL="D2", FORMAT=8.3, UNIT=単位D2); * グループ処理; %BOX_LIST_GROUP_RESULT(ITEM = A1, YLABEL="A1", FORMAT=8.3, UNIT=単位A1); %BOX_LIST_GROUP_RESULT(ITEM = A2, YLABEL="A2", FORMAT=8.3, UNIT=単位A2); %BOX_LIST_GROUP_RESULT(ITEM = A3, YLABEL="A3", FORMAT=8.3, UNIT=単位A3); %BOX_LIST_GROUP_RESULT(ITEM = B1, YLABEL="B1", FORMAT=8.2, UNIT=単位B1); %BOX_LIST_GROUP_RESULT(ITEM = B2, YLABEL="B2", FORMAT=8.2, UNIT=単位B2); %BOX_LIST_GROUP_RESULT(ITEM = B3, YLABEL="B3", FORMAT=8.2, UNIT=単位B3); %BOX_LIST_GROUP_RESULT2(ITEM = C1, YLABEL="C1", FORMAT=8.2, UNIT=単位C1); %BOX_LIST_GROUP_RESULT2(ITEM = C2, YLABEL="C2", FORMAT=8.2, UNIT=単位C2); %BOX_LIST_GROUP_RESULT2(ITEM = C3, YLABEL="C3", FORMAT=8.2, UNIT=単位C3); %BOX_LIST_GROUP_RESULT3(ITEM = D1, YLABEL="D1", FORMAT=8.3, UNIT=単位D1); %BOX_LIST_GROUP_RESULT3(ITEM = D2, YLABEL="D2", FORMAT=8.3, UNIT=単位D2); %BOX_LIST_GROUP_RESULT3(ITEM = D3, YLABEL="D3", FORMAT=8.3, UNIT=単位D3;
マクロ作成の問題点と対策 ●今回の問題点 ■ 類似処理は複数作成する構成にしたため以下の問題が発生した ・同じような要望が来たら類似処理を新規作成しなければいけない(追加要望1) ・類似処理に影響するような要望、修正があると今まで記載した箇所全てに 対応しなければいけない(追加要望2) また、その影響箇所が多いほど修正漏れの危険性が上がる ■ 探索研究であり、多彩な要望があると思われることを考慮に入れていない 作りにしていた ■ マクロは処理をまとめるのに有用な機能であるのにそれが活かされていない
マクロ作成の問題点と対策 ●対策 ■ 類似処理は1つにまとめて修正影響を最小限にする ■ マクロ引数や処理構成はマクロ内にて可変となると思われる部分に着目する 例:図表の作成マクロの引数 ・対象集団(INDATA) ・対象変数とその違い(単位、フォーマット) ・図表の構成(出力テンプレート、出力位置) ・図を作成する場合は要素数で変わる要素 (時点、脚注の位置など)の構文 など %BOX_LIST_RESULT (対象データセット, 対象変数 , 単位, 数値の出力形式 出力テンプレート, 出力位置, 箱ひげ図の構文); %macro BOX_LIST_RESULT INDATA = 変数Aが設定されているデータセット, ITEM = 変数A UNIT = 変数Aの単位 FORMAT = 変数Aの出力形式 TEMPLATE = 出力Excelファイル名 XXX_RC = 出力データ、図の位置 BOX_XXX = 箱ひげ図の各構文(例:values=(1 to 3 by 1)" ) ・・・
マクロ作成の問題点と対策 ●対策 ■ 修正・追加要望は想定外の内容もあり、既存のマクロ修正や追加しなければ 対応出来ない場面はあるため解析結果の作成、マクロ内容に関する情報整理を実施する 「マクロの構成概要」「引数」「マクロ内で呼び出されている他マクロ」など を明確にすることで影響範囲や既存処理での対応が出来るか確認しやすくすると良い
マクロ作成の問題点と対策
まとめ マクロを作る際には以下の点を重視して作成する ・修正時の影響を考慮する(同一処理を色々な箇所で記述しない) ・引数や構成は可変となると思われる部分に着目して設定 → マクロ引数やマクロ処理構成は一例を今回挙げましたが、 より良いマクロの作り方、考え方、整理方法があればご教示いただけますと幸いです 対策を施しても修正・追加の場面はあるので影響調査がしやすいよう、情報整理は重要 → 過去に自分が作った解析プログラムに対して追加要望があった場合に確認しやすくなります。 プログラムを見たけど久しぶりすぎて、構成が思い出せず修正箇所が分からん・・・ となりにくくなると思います
ご清聴ありがとうございました