日本一意孤行?国际原子能机构认为福岛处理水排海计划符合国际安全标准

普里戈津之死!我的三点评论!

从人类历史,看人类未来

目录一览!马工程重点教材《习近平新时代中国特色社会主义思想概论》

从福岛核废水说起:我们是在谈科学还是讲立场

生成图片,分享到微信朋友圈

自由微信安卓APP发布,立即下载! | 提交文章网址
查看原文

如果画一个NEJM 期刊式的生存曲线

谷子歌 统计札记 2023-02-24

一般期刊的生存曲线是这样子的:


而 NEJM 的生存曲线是这样子的:

仔细观察,其实不难发现差别在于:

  • 图中是否有No. at risk 的表格

  • 图中是否内嵌了一个局部放大的K-M曲线

第一点,No. at risk 表格,利用 SAS 自带的生存分析过程步 proc lifetestplot选项的atrisk子选项,可以轻松实现。但自带的过程步,效果确实不敢恭维。不过,好在我们可以用ods output抓取生存曲线的信息,然后用proc sgplot过程中的scatterxaxistable语句完成。具体可见此前的推文:

  • 如何绘制带No.at risk 表格的生存曲线?

第二点,内嵌一个局部放大的 K-M 曲线,利用 SAS 实现起来确实有一定的难度,原因是SAS 无法通过 sgplot过程步直接实现,因此需要借助GTL。

如何利用GTL绘制这种内嵌局部放大的K-M曲线呢? 这里,给大家提供一种思路。

  • 利用自带过程proc lifetestods output抓取 K-M 曲线数据

  • 利用 GTL 及抓取数据集绘制一个原尺寸的,带No. at risk的K-M 曲线

  • 利用 GTL 及抓取数据集绘制一个局部放大的不带No. at risk的K-M 曲线

  • 利用 GTL 定义一个绘图模板,将局部放大图内嵌入原始尺寸图

  • 渲染绘图模板,获得嵌套的 K-M 图

由于 GTL 的语法比较繁杂,对大家来说,比较陌生,不过中间的两个GTL代码,我们可以利用proc sgplottmplout=选项,让 SAS 帮我们自动生成。

具体如何做呢?  请看下面的SAS代码及讲解。

*===1.抓取数据集;
ods output Survivalplot=SurvivalPlotData;
proc lifetest data=sashelp.BMT plots=survival(atrisk=0 to 2500 by 500);
time T * Status(0);
strata Group / test=logrank adjust=sidak;
run;

*===2.获得原始尺寸带no.at risk的GLT代码;
proc sgplot data=SurvivalPlotData noborder noautolegend tmplout="d:\p1.sas";
step x=time y=survival / group=stratum name='s';
scatter x=time y=censored / markerattrs=(symbol=plus) name='c';
scatter x=time y=censored / markerattrs=(symbol=plus) GROUP=stratum;
xaxistable atrisk / x=tatrisk class=stratum colorgroup=stratum;
run;

*===3.获得局部放大尺寸不带no.at risk的GLT代码;
proc sgplot data=SurvivalPlotData noborder tmplout="d:\p2.sas";
step x=time y=survival / group=stratum name='s';
scatter x=time y=censored / markerattrs=(symbol=plus) name='c';
scatter x=time y=censored / markerattrs=(symbol=plus) GROUP=stratum;
xaxis values=(0 to 500 by 100);
yaxis label=" ";
run;

*===4.将局部放大图内嵌与原始尺寸图;
proc template;
define statgraph cars_inset_bar_bar;
begingraph;
layout lattice / columnweights=preferred rowweights=preferred columndatarange=union rowdatarange=union columns=1;
layout overlay / walldisplay=(fill) xaxisopts=(Label="Days from randomization");
StepPlot X=Time Y=Survival / primary=true Group=Stratum LegendLabel="Survival Probability" NAME="s";
ScatterPlot X=Time Y=Censored / subpixel=off Markerattrs=( Symbol=PLUS) LegendLabel="Censored" NAME="c";
ScatterPlot X=Time Y=Censored / subpixel=off Group=Stratum Markerattrs=( Symbol=PLUS) LegendLabel="Censored" NAME="SCATTER";
layout overlay / width=30pct height=35pct halign=0.85 valign=0.85
walldisplay=(fill) opaque=false
yaxisopts=( Label=" " type=linear ) x2axisopts=(labelFitPolicy=Split) xaxisopts=(Label=" " labelFitPolicy=Split type=linear linearopts=( tickvaluelist=( 0 100 200 300 400 500 ) viewmin=0 viewmax=500 ) ) x2axisopts=(labelFitPolicy=Split);
StepPlot X=Time Y=Survival / primary=true Group=Stratum LegendLabel="Survival Probability" NAME="s";
ScatterPlot X=Time Y=Censored / subpixel=off Markerattrs=( Symbol=PLUS) LegendLabel="Censored" NAME="c";
ScatterPlot X=Time Y=Censored / subpixel=off Group=Stratum Markerattrs=( Symbol=PLUS) LegendLabel="Censored" NAME="SCATTER";
endlayout;
endlayout;
Layout Overlay / walldisplay=none xaxisopts=(display=none griddisplay=off displaySecondary=none) x2axisopts=(display=none griddisplay=off displaySecondary=none);
AxisTable Value=AtRisk X=tAtRisk / labelPosition=min Class=Stratum colorGroup=Stratum Display=(Label);
endlayout;
endlayout;
endgraph;
end;
run;

*===5.渲染GTL;
ods html style=gghtml2;
proc sgrender data=SurvivalPlotData template=cars_inset_bar_bar;
run;

具体效果如下图:

我开通了视频号,也许以后分享视频教程就更方便了,欢迎围观。

文章有问题?点此查看未经处理的缓存