|
SAS를 모르는 사람들이 붙인 이름들중에 임상시험에서 아주 자주 쓰이는것이 Waterfall plot입니다. 마치 이런 이름을 모르면 SAS 를 잘 못쓰는사람같이 취급하면서 잘난척 하는 멍청한(?) 사람도 있고 하니 이름들을 알고있는것이 유리합니다. ㅎㅎㅎ
사실 제가 오래전에 SGPlot이 나오기전에 SAS/Graph로 자주 만들고는 했는데 어느날 MD (medical doctor)가 와서는 Waterfall 으로 만들수있냐고 물어보더군요. 그래서 다시 물어봤더니 폭포에서 물이 한쪽으로 흐르는것같이 크기순으로 bar chart를 만들라는 것이었죠, 참나.
어쨋든 말은 거창하지만 사실 SGPlot으로 만들려면 그리 어렵지도 않습니다. 물론 제가 오늘 보여드리는 예를 그냥 써도 좋지만 얼마던지 option을 써서 여러가지로 만들수있습니다.
제가 Final 이라고 데이타를 임의로 만들었는데 필요한 변수는 5개입니다. 사실 3개면 waterfall을 만들수 있는데 BOR변수를 datalabel로 이용했고, DUR변수는 좀더 Fancy한 그래프를 만들려고 썼습니다.
제일 간단한 코드는 언제나 쉽지만 만족할만한 그래프는 아니지만 우선 뼈대하고 생각하고 살을 조금씩 붙여가면 되겠습니다. Figure A1은 그야말로 몇줄안되는 코드로 아주 간단하게 만든것이고 Waterfall이라고 할수없겠죠.
proc sort data=here.final out=final;
by pat;
run;
proc sgplot data=final noborder;
vbarparm category=pat response=cfb / group=group groupdisplay=cluster attrid=group name='a'
datalabel=bor datalabelattrs=(size=5);
xaxis display=(nolabel noticks) valueattrs=(size=6);
yaxis min=-110 max=110 label = "Change from Baseline (%)" labelpos=datacenter
labelattrs=(size=7) valueattrs=(size=6) ;
keylegend 'a'/position=bottom valueattrs=(size=9) titleattrs=(size=7);
run;
여기서 그나마 알아야 하는것이 vbarparm statement인데 vertical bar chart 입니다. Group option을 써서 한 환자 데이타가 아닌 5개 group 데이타를 나타내는것이고요. datalabel 은 CFB (change from baseline) value 뿐이아니라 response value를 Bar 끝에 써주는거죠. xaxis, yaxis, keylegend는 지난번에 설명드린것과 그리 다르지 않습니다. 하지만 이런 간단한 그래프를 어디에다 쓸수있을지 의문이죠.
Figure A2는 최소한 Waterfall 모양으로 바꾸었는데 다른 option들이 있지만 제일 간단한것이 Sorting을 큰것부터 해주면 됩니다. 이왕 하는김에 reference line들을 넣어주면 보기 좋겠죠. 제일 간단한 Waterfall이라고 할수있고 색깔이 없어서 그렇지 쓸만 합니다.
proc sort data=here.final out=final;
by descending cfb;
run;
proc sgplot data=final noborder;
vbarparm category=pat response=cfb / group=group groupdisplay=cluster attrid=group name='a'
datalabel=bor datalabelattrs=(size=5);
xaxis display=(nolabel noticks) valueattrs=(size=6);
yaxis min=-110 max=110 label = "Change from Baseline (%)" labelpos=datacenter
labelattrs=(size=7) valueattrs=(size=6) ;
refline -100 -80 -60 -40 -20 20 40 60 80 100 / axis = y transparency=0.9;
refline 20 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
refline -30 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
keylegend 'a'/position=bottom valueattrs=(size=9) titleattrs=(size=7);
run;
그래도 좀더 보기 좋아보이게 만들면 Figure B라고 할수있는데 그래프자체는 차이가 많지만 사실 코드는 많이 고치지 않았습니다. highlight한것들이 더 새로운 option입니다.
data attrmap;
length ID $ 9 fillcolor $ 10;
input id $ value $10-20 fillcolor $;
show = 'ATTRMAP';
datalines;
group Group A #FE9BB0
group Group B #E64161
group Group C orange
group Group D #ACD890
group Group E #6BBF4B
;
run;
proc sgplot data=final dattrmap=attrmap noborder;
vbarparm category=pat response=cfb / group=group groupdisplay=cluster attrid=group name='a'
datalabel=bor datalabelattrs=(size=5) dataskin=pressed ;
xaxis display=(nolabel noticks) valueattrs=(size=6)
colorbands=odd colorbandsattrs=(transparency=0.85 color=lightblue);
yaxis min=-110 max=110 label = "Change from Baseline (%)" labelpos=datacenter
labelattrs=(size=7) valueattrs=(size=6) ;
refline -100 -80 -60 -40 -20 20 40 60 80 100 / axis = y transparency=0.9;
refline 20 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
refline -30 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
keylegend 'a'/position=bottom valueattrs=(size=9) titleattrs=(size=7);
run;
여기서 다른점을 소개 하자면 dattrmap option입니다. 한마디로 쓸 color들을 미리 데이타에 만들어놓고 dattrmap option을 쓰는것입니다. 지난번에 소개했던 styleattrs datacontrastcolors를 써도 되지만 그것은 순서가 바뀔때마다 group의 색깔이 바뀌는데 이방법은 바뀌지가 않습니다. ID는 여기서는 group변수이고, fillcolor는 bar color입니다. 그러니까 각 group마다 color를 assign 해놓은거죠. 그리고 dataskin은 전에도 소개했지만 좀더 보기좋게 만드는것이고, colorbands는 x-axis의 환자 number하고 lineup 해서 보기 힘들까봐 희미하게나마 색깔을 만든것입니다. 싫은 사람들은 없애도 됩니다.
여기 까지만 해도 쓸만한 Waterfall 입니다. 그런데 만약에 각 환자의 tumor size가 이렇게 바뀌기는 했는데 얼마나 빨리 바뀐것인가를 그래프에 같이 넣자면 DUR변수를 써서 vbarparm을 한번 더 쓰면 되는데 그러면 Figure C1같이 됩니다.
proc sgplot data=final dattrmap=attrmap noborder;
vbarparm category=pat response=cfb / group=group groupdisplay=cluster attrid=group name='a' datalabel=bor
datalabelattrs=(size=5) dataskin=pressed ;
vbarparm category=pat response=dur / group=group groupdisplay=cluster y2axis groupdisplay=cluster
datalabel=dur datalabelattrs=(size=5) dataskin=pressed fillattrs=(color=cxcfcf7f);
xaxis display=(nolabel noticks) valueattrs=(size=6)
colorbands=odd colorbandsattrs=(transparency=0.85 color=lightblue);
yaxis min=-110 max=110 label = "Change from Baseline (%)" labelpos=datacenter
labelattrs=(size=7) valueattrs=(size=6) ;
refline -100 -80 -60 -40 -20 20 40 60 80 100 / axis = y transparency=0.9;
refline 20 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
refline -30 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
keylegend 'a'/position=bottom valueattrs=(size=9) titleattrs=(size=7);
run;
여기서 bar color를 바뀌기 위해서는 fillattrs 를 이용해서 color를 바꾸어봤습니다. 근데 의도는 좋은데 겹쳐져서 쓸모가 없는 그래프가 되었죠?
그래서 필요한것이 offset option입니다. DUR는 위에 그리고 CFB는 밑에다 그릴려면 offsetmin 과 offsetmax를 써서 전체 그래프 space를 나눌수가 있는데 그렇게 만든것이 Figure C2인데 그리 복잡하지는 않습니다.
proc sgplot data=final dattrmap=attrmap noborder;
vbarparm category=pat response=cfb / group=group groupdisplay=cluster attrid=group name='a' datalabel=bor
datalabelattrs=(size=5) dataskin=pressed ;
vbarparm category=pat response=dur / group=group groupdisplay=cluster y2axis groupdisplay=cluster
datalabel=dur datalabelattrs=(size=5) dataskin=pressed fillattrs=(color=cxcfcf7f);
xaxis display=(nolabel noticks) valueattrs=(size=6) colorbands=odd
colorbandsattrs=(transparency=0.85 color=lightblue);
yaxis min=-110 max=110 label = "Change from Baseline (%)" labelpos=datacenter
labelattrs=(size=7) valueattrs=(size=6) offsetmin=0 offsetmax=0.35 ;
y2axis label = "Duration (Day)" labelpos=datacenter labelattrs=(size=7) valueattrs=(size=6)
offsetmin=0.7 offsetmax=0.02 ;
refline -100 -80 -60 -40 -20 20 40 60 80 100 / axis = y transparency=0.9;
refline 20 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
refline -30 / axis = y lineattrs=(pattern=2 thickness=2) transparency=0.8;
keylegend 'a'/position=bottom valueattrs=(size=9) titleattrs=(size=7);
run;
그러니까 x-axis는 그대로 놔두고 Y-axis를 원래 yaxis 외에 y2axis 를 이용해서 나눈거죠.
보통 말하는 Waterfall plot은 Figure B 이니 color도 바꾸고 여러가지 option을 이용해서 원하시는 Waterfall plot을 만드실수 있을겁니다. 하지만 C2 까지도 한번쯤 연습해두시는것을 추천 합니다. 알면 힘인데 이렇게 쉬워보여도 임상시험프로젝트에서 일하는 사람중에 이런것을 잘 할줄아는 사람이 드물어서 제가 올리는 예들만 충분히 소화시켜도 초보라도 잘난척 하실수 있을겁니다. Resume에건 인터뷰할때건... 실지로 일하는데 아주 유용한 skill이고요.
제가 데이타하고 코드까지 올리니까 사실 한 30분이면 충분히 직접 해보실수 있을겁니다. 질문있으시면 연락주시기 바랍니다.
참고로 저는 제글을 copy를 못하게 하지는 않으니까 다른곳에서 쓰셔도 되지만 출처정도는 밝혀주시면 감사하겠습니다.
|
첫댓글 감사합니다.