317 Views
April 15, 25
スライド概要
[第11回大阪sas勉強会]
SAS言語を中心として,解析業務担当者・プログラマなのコミュニティを活性化したいです
第11回 大阪SAS 勉強会 SGPlotでレーダーチャートを描く 関根 暁史 (藤本製薬株式会社) The radar chart which was drawn in SGPlot. Satoshi Sekine Fujimoto Pharmaceutical Corp.
第11回 大阪SAS 勉強会 解析対象集団とかのフロー図を一緒に書いてみよう! 「データステップ100万回 SAS新手一生」 こちらのブログ の真似をして レーダーチャート を描きます。 2
第11回 大阪SAS 勉強会 SOCのデータセット準備 proc format; value body 1="感染症および#寄生虫症" 2="代謝および#栄養障害 " 3="眼障害" 4="心臓障害" 5="胃腸障害" 6="皮膚および#皮下組織 障害"; value rel 1="有害事象" 2="副作用"; run; data SOC; input ae division value @@; format ae body.; format division rel.; format value percentn7.0; label division="因果関係"; datalines; 1 1 .826 1 2 .433 2 1 .86 2 2 .322 3 1 .70 3 2 .65 4 1 .35 4 2 .35 5 1 .843 5 2 .627 6 1 .55 6 2 .431 ; run; 有害事象発現割合 器官別大分類名 3
第11回 大阪SAS 勉強会 回転行列による遷移 x1 𝑐𝑜𝑠 𝜃 = y1 −𝑠𝑖𝑛 𝜃 時計回り 𝑠𝑖𝑛 𝜃 x 𝑐𝑜𝑠 𝜃 y proc ds2; data a/overwrite=yes; dcl double m1 [2,1]; dcl double m2 [2,2]; vararray double a [2,1]; dcl package matrix _m1; dcl package matrix _m2; dcl package matrix _mult; method run(); m1 := (0,&_y.); m2 := (&_cos. &_sin.,-&_sin. &_cos.); _m1 = _new_ matrix( m1, 2, 1 ); _m2 = _new_ matrix( m2, 2, 2 ); _mult = _m2.mult(_m1); _mult.out(a); end; run; quit; 60° 遷移点を結べばレーダーチャー トになる。 4
第11回 大阪SAS 勉強会 polygonで有害事象発現割合を描く proc sgplot data=dummy noautolegend noborder; polygon id=id x=a1 y=a2/group=id lineattrs=(color=black thickness=1.5) name="aaa"; xaxis values=(-120 to 120 by 20) ; yaxis values=(-120 to 120 by 20) ; keylegend "aaa"; run; X軸とY軸を残し ている。 5
第11回 大阪SAS 勉強会 seriesで項目軸を描き入れる proc sgplot data=dummy noautolegend noborder; polygon id=id x=a1 y=a2/group=id lineattrs=(color=black thickness=1.5) name="aaa"; series x=b1 y=b2/ group=rep lineattrs=(color=gray pattern=1 thickness=2) ; xaxis values=(-120 to 120 by 20) display=none; yaxis values=(-120 to 120 by 20) display=none; keylegend "aaa"; run; 原点と120の位置を 結ぶ。 6
第11回 大阪SAS 勉強会 textで文字列を書き入れる 目盛と 項目 proc sgplot data=dummy noautolegend noborder; polygon id=id x=a1 y=a2/group=id lineattrs=(color=black thickness=1.5) name="aaa"; series x=b1 y=b2/ group=rep lineattrs=(color=gray pattern=1 thickness=2); text x=c1 y=c2 text=AEBODSYS/ textattrs=(size=8 color=black) splitchar="#" splitpolicy=splitalways; text x=d1 y=d2 text=text/ textattrs=(size=9 color=black); xaxis values=(-120 to 120 by 20) display=none; yaxis values=(-120 to 120 by 20) display=none; keylegend "aaa"; run; 7
第11回 大阪SAS 勉強会 最後にpolygonでグリッド線を描き入れる 正6角形 proc sgplot data=dummy noautolegend noborder; polygon id=i x=e1 y=e2/group=i lineattrs=(color=lightgray pattern=1 thickness=2); polygon id=id x=a1 y=a2/group=id lineattrs=(color=black thickness=1.5) name="aaa"; series x=b1 y=b2/ group=rep lineattrs=(color=gray pattern=1 thickness=2); text x=c1 y=c2 text=AEBODSYS/ textattrs=(size=8 color=black) splitchar="#" splitpolicy=splitalways; text x=d1 y=d2 text=text/ textattrs=(size=9 color=black); xaxis values=(-120 to 120 by 20) display=none; yaxis values=(-120 to 120 by 20) display=none; keylegend "aaa"; run; 完成 8
第11回 大阪SAS 勉強会 Pythonのpycirclizeによる表現 線種は選択できなさそう。 渡すデータセットの形式 9
第11回 大阪SAS 勉強会 Rのfmsbによる表現 渡すデータセットの形式 (反時計回り) シンボル 軸の最大値 軸の最小値 AE ADR 10
第11回 大阪SAS 勉強会 Excelグラフによる表現 文字の折り返しが効く。 渡すデータセットの形式 SOC 感染症および 寄生虫症 代謝および 栄養障害 眼障害 心臓障害 胃腸障害 皮膚および 皮下組織障害 有害事象 副作用 82.6% 43.3% 86.0% 70.0% 35.0% 84.3% 32.2% 65.0% 35.0% 62.7% 55.0% 43.1% 11
第11回 大阪SAS 勉強会 proc gradarによる表現 filename gplot "./gradar.png"; goptions reset=all noborder hsize=5.15in vsize=4.2in device=png gsfname=gplot; axis1 order=(0 to 1 by .2) value=(height=3pct c=black tick=1 ""); axis2 order=(0 to 1 by .2) value=none; proc gradar data=SOC; chart ae/sumvar=value staraxis=(axis1 axis2 axis2 axis2 axis2 axis2 axis2) noframe height=3.25 lstars=(1 2) wstars=(1.5 1.5) starinradius=0 starcircles=(1.0) cstarcircles=ltgray overlayvar=division cstars=(black black); run; quit; 文字はproc formatを利用。 12
第11回 大阪SAS 勉強会 まとめ ods graphics; ➢ SGPlotはサイズの調整がしやすい。 ➢ SGPlotは文字の折り返しが効く。 文字サイズの調整もしや すい。 ➢ proc gradarやsgannoを使わずとも描ける。 ➢ レーダーチャートは器官別大分類の発現割合の表現に相応しい。 13
第11回 大阪SAS 勉強会 ご清聴有難うございました 14
第11回
大阪SAS
勉強会
付録(1/3)
proc format;
value body
1="感染症および#寄生虫症" 2="代謝および#栄養障害" 3="眼障害"
4="心臓障害" 5="胃腸障害" 6="皮膚および#皮下組織障害";
value rel 1="有害事象" 2="副作用";
run;
data SOC;
input ae division value @@;
format ae body.;
format division rel.;
format value percentn7.0;
label division="因果関係";
datalines;
1 1 .826 1 2 .433
2 1 .86 2 2 .322
3 1 .70 3 2 .65
4 1 .35 4 2 .35
5 1 .843 5 2 .627
6 1 .55 6 2 .431
;
run;
data AEBODSYS;
set SOC end=eof;
by notsorted ae;
retain rep -1;
if first.ae then rep+1;
AEBODSYS=vvalue(ae);
pct=put(round(value*100,.1),best.-l);
keep division rep AEBODSYS pct;
if eof then call symputx("_last",rep+1);
run;
/*有害事象*/
data pre;
set AEBODSYS(where=(division=1));
theta=rep*360/&_last.;
cos=put(round(cos(theta*constant('pi')/180),.001),best.-l);
sin=put(round(sin(theta*constant('pi')/180),.001),best.-l);
_rotate='%rotate('||strip(pct)||','||strip(cos)||','||strip(sin)||')
;';
output;
if rep=0 then do; rep=&_last.; output; end;
run;
proc sort data=pre; by rep; run;
data post; run;
%macro rotate(_y,_cos,_sin);
proc ds2;
data a/overwrite=yes;
dcl double m1 [2,1];
dcl double m2 [2,2];
vararray double a [2,1];
dcl package matrix _m1;
dcl package matrix _m2;
dcl package matrix _mult;
method run();
m1 := (0,&_y.);
m2 := (&_cos. &_sin.,-&_sin. &_cos.);
_m1 = _new_ matrix( m1, 2, 1 );
_m2 = _new_ matrix( m2, 2, 2 );
_mult = _m2.mult(_m1);
_mult.out(a);
end;
run;
quit;
data post; set post a; if a1=. then delete; run;
%mend rotate;
15
第11回 大阪SAS 勉強会 付録(2/3) data _null_; set pre; call execute(_rotate); run; data ae; set post; id="有害事象"; run; /*副作用*/ data pre; set AEBODSYS(where=(division=2)); theta=rep*360/&_last.; cos=put(round(cos(theta*constant('pi')/180),.001),best.-l); sin=put(round(sin(theta*constant('pi')/180),.001),best.-l); _rotate='%rotate('||strip(pct)||','||strip(cos)||','||strip(sin)||') ;'; output; if rep=0 then do; rep=&_last.; output; end; run; proc sort data=pre; by rep; run; data post; run; data _null_; set pre; call execute(_rotate); run; data adr; set post; id="副作用"; run; /*レーダー部*/ data radar; set ae adr; run; /*項目軸*/ data pre; set AEBODSYS(where=(division=1)); theta=rep*360/&_last.; cos=put(round(cos(theta*constant('pi')/180),.001),best.-l); sin=put(round(sin(theta*constant('pi')/180),.001),best.-l); _rotate='%rotate(120,'||strip(cos)||','||strip(sin)||');'; run; proc sort data=pre; by rep; run; data post; run; data _null_; set pre; call execute(_rotate); run; data post; set post; rep=_n_-1; run; data line; set post; output; by rep; if last.rep then do; a1=0; a2=0; output; end; rename a1=b1 a2=b2; run; /*項目ラベル*/ data label; merge AEBODSYS(where=(division=1)) post; keep AEBODSYS a1 a2; rename a1=c1 a2=c2; run; /*軸ラベル*/ data text; text="100.0%";d1=0;d2=100;output; text="80.0%";d1=0;d2=80;output; text="60.0%";d1=0;d2=60;output; text="40.0%";d1=0;d2=40;output; text="20.0%";d1=0;d2=20;output; text="0.0%";d1=0;d2=0;output; run; 16
第11回 大阪SAS 勉強会 付録(3/3) /*グリッド線*/ data pre; do i=0 to 100 by 20; do theta=0 to 360 by 360/&_last.; cos=put(round(cos(theta*constant('pi')/180),.001),best.-l); sin=put(round(sin(theta*constant('pi')/180),.001),best.-l); _rotate='%rotate('||strip(put(i,best.))||','||strip(cos)||','||strip (sin)||');'; output; end; end; run; data post; run; data _null_; set pre; call execute(_rotate); run; data grid; merge pre post; drop cos sin _rotate; rename a1=e1 a2=e2; run; title; ods listing gpath="."; ods graphics/reset width=3.3in height=3.0in imagename="radar" noborder; proc sgplot data=dummy noautolegend noborder; polygon id=i x=e1 y=e2/group=i lineattrs=(color=lightgray pattern=1 thickness=2); polygon id=id x=a1 y=a2/group=id lineattrs=(color=black thickness=1.5) name="aaa"; series x=b1 y=b2/ group=rep lineattrs=(color=gray pattern=1 thickness=2); text x=c1 y=c2 text=AEBODSYS/ textattrs=(size=8 color=black) splitchar="#" splitpolicy=splitalways; text x=d1 y=d2 text=text/ textattrs=(size=9 color=black); xaxis values=(-120 to 120 by 20) display=none; yaxis values=(-120 to 120 by 20) display=none; keylegend "aaa"; run; data dummy; merge radar line label text grid; run; 17