SAS GTL 统计制图的自动化实现
2019-07-10东南大学公共卫生学院流行病与卫生统计学系210009
东南大学公共卫生学院流行病与卫生统计学系(210009)
秦 扬 潘俊霞 刘 沛△
【提 要】 目的 为利用SAS图形模板语言(graph template language,GTL)实现疫苗临床试验统计制图的自动化提供方法学参考,以提高临床试验制图效率,降低宏程序使用门槛提供便利。方法 利用SAS强大的数据处理能力、SAS GTL灵活的图形展现能力构建SAS宏程序,结合excel参数表,实现临床试验批量自动化制图功能。结果 通过SAS自动化宏程序批量绘制疫苗临床试验中两种特殊图形:实验室指标基线随访散点图和不良事件发生率及相对风险图。结论 利用SAS数据处理、GTL图形输出可构建SAS宏程序,结合excel参数表可实现临床试验制图的批量自动化。
在疫苗临床试验统计分析报告中,将统计结果以图形方式呈现,不仅可缩短报告篇幅,而且能重点突出试验的关键信息,常常起到画龙点睛之作用。目前统计制图已有较多工具,如excel、R、Graphpad Prism等软件。这些工具虽然各有特色和优势,但均需要从SAS中导出相应数据集实现绘图。在临床试验中,欧美发达国家及我国CFDA均推荐使用SAS进行统计分析,统计报告中的制图数据需要来自SAS软件的分析结果。如果利用以上制图软件绘图,需要将SAS产生的结果数据导出至该软件,一方面使结果表达的可溯源性受到了挑战,另一方面也容易出现软件兼容与更多意外的风险。更为重要的是,由于临床试验一次往往需要产生几十甚至上百张图表,反复修改宏参数极易出现人为操作失误等问题,不断调试宏程序也需要花费时间和人力。
在我国卫生统计学界,SAS虽然一直是统计分析的权威软件,但其绘图功能一直被认为不够完善。值得注意的是,自SAS9.2推出ODS Graphics System以来,改变了这种局面。而最新的SAS9.4无论是在绘图类型与绘图功能的细节方面均进行了扩展和完善,这些特点都为自定义编制SAS宏,实现自动化的图形输出提供了便利条件。本文针对目前国内缺乏SAS GTL介绍的情况下,在介绍GTL基本功能的基础上,通过构建SAS宏程序并结合excel参数赋值实现统计制图自动化,以期为提高临床试验制图效率,降低宏程序使用门槛提供便利。
SAS GTL简介
SAS作为一款优秀的统计分析软件,其统计绘图功能却一直为人诟病,直到SAS9.2 ODS Graphics System的推出改变了这种局面。与传统的SAS GRAPH绘图模块相比,ODS Graphics采用模板驱动的原理,利用ODS系统读取绘图模板、样式模板及相应的数据以实现图形的输出[1]。另外,SAS ODS graphics system从9.3版本之后并入Base模块,意味着无需额外付费即可使用。更重要的是,ODS graphics将所有图形的绘制都统一至同一过程步,使其语法变得更加简洁统一,其核心GTL更是利用“blocks”概念实现了代码内部的逻辑控制。ODS Graphics模块包括三个部分:SG绘图过程步(Statistical Graphics Procedures,SG Procedures)、ODS图形设计器(ODS Graphics Designer)和ODS图形编辑器(ODS Graphics Editor),而GTL则是整个模块最底层的支持代码。其中,SG过程步可实现基本图形的输出,ODS Graphics Designer利用菜单式点选实现作图,ODS Graphics Editor则在后期对图形进行简单的编辑。直接利用GTL绘图可定制更加灵活的个性化图形,它以一定程度的程序复杂性实现更加灵活的图形元素修改。GTL的语法简洁统一,其图形实现可分为以下两个步骤:
步骤1:编译(compile)
proc template;
define statgraphtemplate-name;/*定义图形模板名称*/
begingraph;/*开始图形绘制*/
GTL-statements;/*图形参数修改*/
endgraph;/*结束图形绘制*/
end;/*结束模板定义*/
步骤2:执行(execute)
proc sgrenderdata=data-source/*定义数据集名称*/template=template-name/*定义模板名称*/;
即首先自定义图形模板,提交后得以编译存储,再结合作图数据对象创建图形输出。可以看到,相比传统的Graph绘图模块,GTL的语法更为简洁,并在绘图模板定义时呈现出代码块嵌套的特点。所谓代码块(Blocks),即一对对称的绘图语句,它标志着特定功能代码的开始与结束。比如面的define statgraph语句与end语句、begingraph语句与endgraph语句的成对存在。另外,GTL语句的书写也符合代码块的特点,如layout语句与endlayout语句、cell语句与endcell语句等。代码块的相互嵌套是不可逆的,比如layout语句必须嵌套在begingraph代码块当中,cell语句必须嵌套在layout语句当中。“block”概念的存在使得程序的可读性大大增加,需要注意的是GTL也给这种嵌套以一定的规则。GTL-statements是可变代码,它包括布局语句(layout_statements)与图形元素语句。其中,图形元素可包括形状、图例与文字元素等。GTL允许自由地进行图形布局设计,利用三类布局模板(layout statements)可分别创建页面单图、多图和分类面板图;不同的统计图形选择不同的作图语句(plotstatements),同时指定相应的图形参数选项;利用图例语句(legendstatements)、文字语句(textstatements)及相应的选项可为图形指定图例与相应文字如标题、脚注等。
需要明确的是,ODS Graphics输出的图形为模板驱动图形,sg过程步通过调用绘图数据对象、加载已编译存储的绘图模板,并采用当前ODS destination指定的样式模板,再输出终端绘制图形。因此ODS绘图时必须至少存在一个活动的ODS终端。我们通过ODS语句指定图片路径、ODS Graphics语句指定图片属性如图片名称、格式、分辨率等,从而在ODS终端输出高质素的标量、矢量统计图形。
自动化绘图的宏程序实现
1.制图宏程序的建立
与excel、GraphPad不同的是,通过调用自定义的SAS宏程序[2-3],我们可以避免同类型图形的手工重复制图。本研究制图宏程序分为三部分:数据处理、GTL绘图与ODS输出控制。
EpiData库或电子数据采集(electric data capture,EDC)中的临床试验数据经导出、初步处理成源数据后可调用宏程序,经宏中数据处理部分成为GTL所需的作图数据集,即sg render过程步的data_source。提交GTL模板定义实现编译查错并存储,Sg render过程步将数据对象与模板定义相结合生成图形结果,同时利用ODS系统将图形输出为特定格式,可指定相应的输出样式、输出路径等。ODS输出样式与图形模板定义共同影响图形的表现。利用ODS系统,我们可以指定是否生成单独的图片格式文件或者将图形作为输出的一部分、图形为标量还是矢量图以及图形的具体物理属性如路径、名称、格式等。宏内参数包括三种,一般参数、传递参数与图形参数。一般参数指图形的名称、格式、存储路径等全局宏变量;传递参数则是指作图数据集、作图参数;图形参数则是一些可变的图形属性如图片标题、轴标签、不同组别线型、颜色等。
2.SAS与excel参数表的连接[4]
在实际操作过程当中,每输出一张图形需要调用一次宏程序,并修改图形参数。当输出大量图形时,频繁的调用将导致出错的风险增多。以excel外部参数表的形式统一整理绘图宏参数并实现修改,可实现批量出图并降低宏程序使用难度。通过将excel参数表以SAS数据集的形式导入SAS宏程序,从而实现了对GTL程序中宏变量的批量赋值与修改,详见表1。
表1 某临床试验的excel参数表模板(节选)
使用者可直接根据参数表中对宏参数的描述修改对应宏参数,通过修改value1-N列的对应参数值,可同时批量输出N张不同的图形。
GTL宏程序实例
1.实验室指标基线随访散点图
实验室指标基线随访散点图采用矩阵图的表现形式,在同一图形面板中完整地展示了受试者不同实验室指标在不同时间点的变动情况[5]。实验室指标矩阵图可以视为临床试验报告中正常异常交叉表的图形化表达,以矩阵图中散点直观展示的可视化技术取代了表格的笼统概述,形象地突出了安全性分析中的异常信号。图1显示的是某临床试验受试者第3天、7天、14天、28天部分血常规、血生化指标与基线的对比情况。
图1 部分血常规/血生化指标基线随访散点图
图中指示线为相应指标的正常值上限(upper limit of normal,ULN)可作为个体正常、异常值的分界。我们选取部分适宜制图的血常规、血生化指标进行展示,并在数据处理阶段对异常无临床意义的值进行了剔除。即显示异常的个体均为有临床意义的个体,这些个体的筛选号被直观标识出来。如图可见,筛选号为S074的个体在第7天出现了谷丙转氨酶的升高,在第14天呈现出谷丙转氨酶的持续升高并伴有总胆红素的升高,提示肝功能严重受损。对于这样的个体,在安全性评价中应重点关注,追溯其异常是否与干预措施有关。
实验室指标基线随访散点图制图的具体步骤:
1.填写参数表:
填写相应的外部参数表以修改必要的图形属性参数。
2.调用制图宏:
通过修改宏内参数值以实现制图,其中exceladdress为参数表位置:%datapanel(exceladdress=%str(D:assignmentsas-drawing参数表.xlsx),sheet=格子图)
3.宏内GTL模板定义:
proc template;
define statgraph datapanel;/*图形模板定义*/
mvar TITLE ROWVAR COLUMNVAR START HEADERLABELDISPLAY XLABEL XTYPE YLABEL YTYPE X Y GROUP DATALABEL REFERCENCELINEVALUE1 REFERCENCELINEVALUE2 BORDER OPAQUE LINECOLOR1 LINECOLOR2;/*声明宏变量*/
nmvar LINEPATTERN1 LINETHICKNESS1 LINEPATTERN2 LINETHICKNESS2;
begingraph;
entryfootnote TITLE;/*定义脚注*/
layout datalattice rowvar=ROWVAR columnvar=COLUMNVAR/start=START headerlabeldisplay=HEADERLABELDISPLAY rowaxisopts=(display=(XLINEDISPLAY XLABELDISPLAY XTICKSDISPLAY XTICKVALUESDISPLAY)type=XTYPE linearopts=(thresholdmax=1)label=XLABEL labelattrs=(size=9pt))columnaxisopts=(display=(XLINEDISPLAY XLABELDISPLAY XTICKSDISPLAY XTICKVALUESDISPLAY)type=YTYPE linearopts=(thresholdmax=1)label=YLABEL labelattrs=(size=9pt));/*格子图分类变量定义及轴选项*/
layout prototype;/*格子图内容定义*/
scatterplot x=X y=Y/group=GROUP name=“datapanel”
datalabel=DATALABEL;/*散点图定义*/
referenceline REFERCENCELINEVALUE1/lineattrs=
(color=LINECOLOR1 pattern=LINEPATTERN1 thickness=LINETHICKNESS1 pt);/*辅助线定义*/
referenceline REFERCENCELINEVALUE2/lineattrs=
(color=LINECOLOR2 pattern=LINEPATTERN2 thickness=LINETHICKNESS2 pt);
endlayout;
sidebar;
discretelegend “datapanel”/border=BORDER opaque=OPAQUE;/*图例定义*/
endsidebar;
endlayout;
endgraph;
end;
run;
2.不良事件发生率及相对风险图
不良事件发生率及相对风险图在临床试验不良事件描述中利用传统的森林图[6],通过计算组间效应量RR及其95%可信区间,直观展现了所关注的不良事件发生率与相应的组间差异。另外,还可以进行纵向间不良事件发生的比较。根据研究目的,在森林图中按照一定规律对不良事件进行排序,可以直观、突出地显示最需要关注的不良事件。本例中我们以不良反应发生率的总和作为排序的标准。图2显示的是某临床试验中28天非征集不良事件的发生率与组间差异情况。
图2 不良事件发生率及相对风险图
图中将不良事件发生率以从高到低的顺序排序,右侧显示了不良事件不同剂量组间的RR值及其95%置信区间。由图可见,RR=1的标识线穿过所有不良事件的95%置信区间范围,提示不良事件组间差异无统计学意义。
绘制不良事件发生率及相对风险图的具体步骤:
1.填写参数表:
2.调用制图宏:
通过修改宏内参数值以实现制图,其中exceladdress为参数表位置:%forest(exceladdress=D:assignmentsas-drawing参数表.xlsx,sheet=多框图,group=group,zzname=zzname,group1=高剂量组,group2=低剂量组)
3.宏内数据处理与ODS控制代码:
(1)数据处理:
/*分析数据集>制图集*/
ods trace on;
ods output CrossTabFreqs=p(keep=&group.&zzname.rowpercent frequency rename=(rowpercent=p)where=(not missing(&group.)and not missing(&zzname.)))CrossTabFreqs=percent(keep=percent &zzname.);
proc freq;
tables &group.*&ZZNAME.;
run;
ods output close;
/*生成p和rr*/
data p1;
set p(rename=(frequency=a)where=(&group.="&group1."));
run;
data p2;
set p(rename=(&group.=group1 p=p1 frequency=c)where=(group1="&group2."));
run;
data _temper;
merge p1 p2;
run;
data rr(keep=&zzname.rr lowerrr upperrr where=(not missing(rr)));
set _temper;
b=32-a;
d=33-c;
rr=p/p1;
SE=1/a+1/b +1/c +1/d;
lowerrr=exp(log(RR)-1.96 *SE);
upperrr=exp(log(RR)+1.96 *SE);
run;
/*p和rr连接*/
proc sql;
create table unsort_forest as
select rr.*,&group.,p
from rr left join p
on rr.&zzname.=p.&zzname.;
/*排序Ae*/
data percent;
set percent(firstobs=37 obs=53);
run;
proc sort data=percent;
by descending percent;
run;
data percent;
set percent;
id=_n_;
run;
proc sql;
create table forest as
select unsort_forest.*
from unsort_forest left join percent
on percent.&zzname.=unsort_forest.&zzname.
order by id;
(2) ODS控制语句:
ods graphics/reset imagename=“&title.”noborder outputfmt=&outputfmt.width=&width.height=&height.;/*控制图形属性*/
ods _all_ close;/*关闭所有ODS目标*/
ods listing gpath="&gpath."style=&style.;/*只打开listing目标,控制图形属性*/
proc sgrender data=&data.template=forest;
run;
ods listing close;/*listing目标关闭*/
ods html;
讨 论
ODS Graphics是SAS 9.2新推出的绘图模块,它颠覆了人们对于SAS制图的认知。而图形模板语言GTL是ODS Graphics System最底层的作图代码,它可以实现几乎所有绘图元素的修改。国外对于SAS GTL的介绍大多见于SAS相关会议,而国内GTL的应用文章也不多见。本研究以疫苗临床试验中两种特殊图形为例,介绍了SAS 9.4最新版本中不同图形的SAS GTL代码编写及宏程序实现过程,并结合excel参数表批量赋值实现了图形输出自动化。GTL通过在template过程步中变换作图语句及相应参数指定绘图模板,编译后结合sgrender过程步指定作图数据实现制图。其语法结构规范统一,代码块间相互嵌套,可读性强且代码量少。与传统的Graph绘图模块相比,它将不同种类图形的绘制汇总至同一过程步,克服了绘图过程步分散、绘图代码风格混乱的缺点。需要注意的是,GTL的灵活性与复杂性相伴,大量的图形选项[7]是学习的重点与难点。另外,利用excel参数表与宏的结合,我们可以规范化、批量化指定宏参数,这样不仅减轻了使用者的宏程序修改难度,同时也有助于实现临床试验图形制作的自动化。