引言
科研过程,是个不断推翻、更新的过程。数据分析过程中,数据库变量越来越多,reviewer或砖家们提个小建议可能就改变整个结果,被逼着一遍又一遍更新图表。笔者年少之时曾经苦于手动挡的Ctrl+C,Ctrl+V,当面对茫茫多变量结果时候,一不小心就出错,心中油然狂奔过万千草泥马大军。
话说,天下苦Ctrl+C久已。那有没有一种自动绘制SCI表格的方法?答案是肯定的。随着软件普及和学术积累,越来越多的方法可以实现SCI表格一键出图。如何快速整理出一张干净方便且具有统计p值的基线表和主分析表是科研速度的关键。统计只是工具,不管白猫黑猫抓到老鼠就是好猫。工具好比菜刀,统计图表就是菜品,统计图是素菜,统计表就是荤菜。
SAS不像SPSS那般中庸圆润,也不如新贵R清丽激情,更像是一个岁月静好的学术派老妪。曾几何时,SAS是各大医学院校研究生统计课的必修课,也是笔者本科时第一款统计软件。随着大数据时代的到来,面对纷繁复杂的各类新派统计方法学,SAS似乎越发暮霭沉沉,R python则粉墨登场。但不管怎么说,SAS依旧有着最严谨的统计公式,是统计推断参数估计的镇海神针,在经典医学统计领域有着不可取代的信誉背书(图1)。
图1 SAS 经典统计不可撼动
相比R有大名鼎鼎的基线表格Tableone包,SAS表格之名似乎有点聊胜于无。诚然SAS制作论文美图的能力可以说是抓襟见肘,但它表格能力却是被极度低估的。SAS其实有比R更全面更牛逼的自动化SASmacros (宏程序)。例如,SAS自动输出基线表和多因素OR值与置信区间,最终直接给出docx文档,相当之牛逼,只是缺少了推广的土壤!究其原因有3点,1是SAS收费且体积庞大,2是宏编程看懂需要扎实的SAS语言基础,3是缺乏文章入门介绍这些macro。
鉴于以上原因,笔者实战角度出发撰写此文,以飨读者。
1. 免费的SAS云端
进入https://welcome.oda.sas.com/login,SAS cloud网站注册登记,可免费云端使用SAS studio。但是有卡顿,远不如PC端丝般顺滑。SAS安装程序可去人大论坛或0daydown下载。
图2 SAS cloud
2. 现有的SAS macro
笔者检索pubmed (SAS macros[TITLE]),2010.1-2021.8共有24篇文献,其中涉及到table的宏仅有 %ggbaseline1, %svy_freqs2。由于本文目的是整理最便捷的表格自动化输出,所以对于统计建模macro细分到各个模型介绍。Pubmed遗漏了最重要的一篇文献, 埃默里大学的Liu教授发表在F1000Research上,详尽的分享了从基线表到统计表15个SAS macro(如表1)3。宏下载地址,https://winshipcancer.emory.edu/research/shared-resources/biostatistics.html。
使用这些宏的好处是它们可以一次处理大量变量并创建专业、一致且可解释的汇总表,而无需从 SAS 输出手动复制粘贴到最终报告。此外,它还可以生成可读且简洁的 SAS 代码,最重要的是可以随着研究项目的发展而更轻松地进行自动维护和修订。
表1 SAS macro 表格自动化
3. 一键绘表实战
这里引用https://biostat.app.vumc.org/wiki/Main/DataSets →rhc.csv数据集。rhc.csv 数据集用于探索右心导管手术在重症患者初始护理中的有效性,已发表JAMA杂志论文, PMID: 8782638。主要结局变量为death,手术方式变量为swang1,其他均为协变量,为了演示宏笔者自行添加了随访时间time变量。变量精简如下表2。
表2 rhc.csv数据分析部分变量
SCI基线表运行SAS语法,版本号SAS9.4 TS1M6,红色和灰色部分根据说明替换即可,笔者已修复文献bugs。
/*macrodir为宏放置路径,dir为输出路径*/
dm'log;clear;output;clear;odsresults;clear';
%let macrodir=D:\写书\SAS表格宏\Emory-Yuan-BBISR-SAS-Macros-6d8a010\;
%include"¯odir.DESCRIPTIVE V16.sas";
%include "¯odir.UNI_CATV30.sas";
%include "¯odir.UNI_NUMV9.sas";
%include "¯odir.UNI_LOGREGV15.sas";
%include "¯odir.UNI_PHREGV26.sas";
%include"¯odir.MULTIPLE_LOGREG V16.sas";
%include"¯odir.MULTIPLE_PHREG V21.sas";
%include "¯odir.LOGREG_SELV15.sas";
%include "¯odir.PHREG_SELV23.sas";
%include"¯odir.PlSurvivalTemp V5.sas";
%include "¯odir.KM_PLOTV23.sas";
*%include "¯odir.TableTemplate.sas";
%let dir = D:\写书\SAS表格宏\output\;
/*事先转换rcs.sas7bdat, 需要要运行 SAS9.4英文版,SAS中文版出错*/
libname casedata 'D:\写书\SAS表格宏';
DATA rhc; set casedata.rhc;
RUN;
/*%let 定义协变量;分类、连续变量;本例精简变量*/
/*PROC format; value death 1 ="Yes" 0= "No";run;*/
%let cat_var=sex_01 race_123 income_1234 cat1_123456789 dnr1_01 ca_012 resp_01card_01 neuro_01 gastr_01 renal_01 meta_01 hema_01 seps_01 trauma_01 ortho_01swang1_01;
%let num_var= age das2d3pc surv2md1 aps1 scoma1 wtkilo1 temp1 meanbp1resp1 hrt1 pafi1 paco21 ph1 wblc1 hema1 sod1 pot1 crea1 bili1 alb1 cardiohxchfhx dementhx psychhx chrpulhx renalhx liverhx gibledhx malighx immunhxtranshx amihx ;
/*----------------baseline基线表---------------------*/
TITLE 'Table 1 Descriptive Statisticsfor All Variables';
/* swang1 death 为y,其他为cox; 输出字典*/;
%DESCRIPTIVE (DATASET=rhc,
CLIST = death_01&cat_var, NLIST = &num_var, OUTPATH= &dir, dictionary = T,
FNAME=Table 1 Descriptive Statisticsfor All Variables, DEBUG=F); TITLE;
/*-------------------univariateanalysis---------------------*/
/*单因素F,X2分析;NONPAR=F 不然大样本计算fisher exact很久*/
TITLE 'Table 2 Univariate Associationwith Progression';
%UNI_CAT (dataset = rhc,
OUTCOME =death_01, CLIST = &cat_var, NLIST = &num_var,
nonpar = F, rowpercent = F, SPREAD = T, orientation= Landscape, outpath = &dir,
fname = Table 2 Univariate Associationwith Progression); TITLE;
/*%UNI_CAT 对应Y=01,%UNI_NUM对应y连续 */
/*-------------------univariatelogistic-----------------------*/
/*单因素logistic分析,省略一些变量测试*/
TITLE'Table 3 Univariate logistic association with death';
/*设置哑变量参考值*/
%letcat_var_ref = sex_01(ref="0")*race_123(ref="1")*income_1234(ref="1")
*cat1_123456789(ref="1")*swang1_01(ref="0");
/*原数据字符型,则%let cat_var_ref=sex(ref="Female");分类321,默认降序3参考(DESC)*/
ods listing close; ods html close;
%UNI_LOGREG ( DATASET = rhc,
OUTCOME = death_01,EVENT = '1', CLIST = &cat_var_ref,NLIST = &num_var, OUTPATH = &dir, FNAME= Table 3 Univariate logistic); TITLE;
/*-----------------univariatecox---------------------*/
/*单因素 cox分析,log-rank检验*/
TITLE 'Table 4 Univariate Cox';
/*测试time,censor*/
data rhc_cox; set rhc; if death_01=0then censor=1; else if death_01=1 then censor=0;RUN;
%UNI_PHREG (dataset =rhc_cox,
EVENT = time,CENSOR = censor, CLIST = &cat_var_ref, NLIST = &num_var ,
logrank=T, outpath = &dir, fname =Table 4 Univariate Cox Survival Analysis); TITLE;
/*----------------- Multivariablelogistic--------------------*/
/*多因素logistic分析,Backward selection纳入P<0.1*/
TITLE 'Table 5 Multivariable LogisticRegression Model';
%LOGREG_SEL ( DSN = rhc,
OUTCOME = death_01,EVENT = '1', VAR = &cat_var&num_var, CVAR = &cat_var_ref, INC = 1, SLSTAY = 0.1, CLNUM =F, OUTPATH=&dir, FILENAME=Table 5 Multivariable Logistic Regression Model); TITLE;
/*----------------- Multivariablecox-------------------*/
/*多因素 cox分析,Backwardselection纳入P<0.1 */
TITLE 'Table 6 Multivariable CoxProportional Hazard Model ';
%PHREG_SEL (DSN = rhc_cox,
EVENT = time,CENSOR = censor, VAR = &cat_var&num_var, CVAR = &cat_var_ref, INC = 1, SLSTAY = .10, CLNUM = T,OUTPATH = &dir, FILENAME = Table 6 Multivariable Cox Proportional HazardModel for Overall Survival); TITLE;
/*---------------- 补充%ggbaseline多分组基线表------------*/
/*经测试,存在%let x1=&x;等诸多问题,不适用于SAS9.4TS1M6*/
最终输出结果见output文件夹下.doc文档,选择性依据SCI杂志进一步编辑样式。
小结
SAS macro一键绘制基线表、单因素、多因素表,足够应付80%的日常统计。在课题之初,数据探索阶段通过上述“6板斧 (6个macro)”,可以快速批量获得项目idea。
有此自动化表格神器,从此课题中期汇报,进展,总结,瑟瑟发抖的不是你而是那些数据了。
1. GuHQ, Li DJ, Liu C, Rao ZZ. %ggBaseline: a SAS macro for analyzing and reportingbaseline characteristics automatically in medical research. Ann Transl Med2018;6(16):326.doi:10.21037/atm.2018.08.13
2. Muthusi J, Mwalili S, Young P.%svy_logistic_regression: A generic SAS macro for simple and multiple logisticregression and creating quality publication-ready tables using survey ornon-survey data. PLoS One 2019;14(9):e0214262.doi:10.1371/journal.pone.0214262
3. Liu Y, Nickleach DC, Zhang C, Switchenko JM,Kowalski J. Carrying out streamlined routine data analyses with reports forobservational studies: introduction to a series of generic SAS ((R)) macros.F1000Res 2018;7:1955.doi:10.12688/f1000research.16866.2