SAS软件在医疗机构传染病信息报告质量调查中的应用
2017-06-05无锡市锡山区疾病预防控制中心214000
无锡市锡山区疾病预防控制中心(214000)
李 杰△ 顾 月 邵佳奇 吕 莉 孙凤妹 黄 琦
·计算机应用·
SAS软件在医疗机构传染病信息报告质量调查中的应用
无锡市锡山区疾病预防控制中心(214000)
李 杰△顾 月 邵佳奇 吕 莉 孙凤妹 黄 琦
随着国家疾病预防控制信息化建设的发展,自2004年我国传染病网络直报系统运行以来,需定期对各类医疗机构的传染病监测报告质量进行检查。国内已有不少学者发表过关于医疗机构传染病报告质量现状调查的相关文献[1-2],但几乎所有文献的调查方法均为分层抽样结合人工审查的方式,势必带来抽样误差、涵盖范围窄、工作量大等问题。而医院信息系统(hospital information system,HIS)的开发虽然实现了对病人诊疗信息数据的电子化收集、存储和处理[3],但迄今没有统计软件专门模块来实现网报质量评价指标的自动计算功能。本文主要初步探讨利用SAS软件编程法对医疗机构HIS系统门诊日志自动核查,发现迟报、漏报、信息不一致等情况并计算相应的评价指标,同时自动生成详细Excel报表[4-5]。
资料与方法
1.资料来源
病人诊疗信息来源于各医疗机构HIS系统(版本、格式不一定相同)提供的门诊日志信息,包含姓名、性别、年龄、诊断名称、发病日期、诊断日期等基本资料。疫情资料来源于中国疾病监测信息报告管理系统。
2.评价指标
传染病信息报告质量主要评价指标包括[6],①报告率/漏报率:某时间段内网络报告(漏报)传染病数/同期确诊传染病总数×100%;②及时率:某时间段内及时报告的传染病数/同期网络报告传染病总数×100%;③完整率:某时间段内填写完整纸质报告卡数/同期网报卡片总数;④一致率:某时间段内姓名、性别、年龄等信息一致的网报卡片数/同期网报卡片总数;⑤逻辑准确率:某时间段内逻辑准确卡片数/同期网报卡片总数;⑥综合指数:(报告率+及时率+完整率+准确率+一致率)/5。
3.SAS编程与说明
主要通过SAS 9.3版软件的BASE模块、SQL模块及宏程序等功能来实现数据的整理、拼接、筛选和报表输出等[7-9]。
(1)数据的整理
考虑到不同医疗机构的HIS系统导出的门诊日志信息大相径庭,如变量名称、个数、出现的顺序、输入输出格式等;同时中国疾病监测信息报告管理系统导出的病人资料(以下称为网报信息)的数据格式不能直接用于SAS软件的处理,因此,在进行统计处理前需利用%label宏程序对原始日志和网报信息进行数据的整理,包含数据导入、变量提取、规格化命名及赋予标签、数据格式的转化等[10]。
%macro label(path=,mz=,zl=,yymc=,name=);/*path是数据集存放路径,mz是门诊日志或网报信息存放的sheet,zl是变量标签存放的sheet,yymc是医疗机构名称,name是输出sas数据集名称*/
proc import datafile=“&path&yymc..xls” out=__mzrz replace;sheet=“&mz”;run;
proc import datafile=“&path变量标签表.xls” out=__var_label replace;sheet=“&zl”;run;
/*变量标签表第一列为原始变量名称,第二列为标准化变量名称,第三列为变量标签*/
proc sql;select count(*)into:num from__var_label;quit;
data__var_label(drop=blm var label);attrib_blm length=$40_var length=$40_label length=$40;set__var_label;_blm=blm;_var=var;_label=label;run;
proc sql;select_blm,_var,_label into:blm1-:blm%trim(%left(&num)),:var1-:var%trim(%left(&num)),:label1-:label%trim(%left(&num))from__var_label;quit;
data_mzrz;attrib yljg_name length=$40;set__mzrz;
%do i=1%to #
&&&var&i=&&&blm&i;
label &&&var&i=“&&&label&i” yljg_name=“医疗机构名称”;
yljg_name=“&yymc”;
keep &&&var&i yljg_name;
%end;
run;
%if “&mz”=“门诊”%then%do;
data &name.(rename=(jzrq_mz1=jzrq_mz fbrq_mz1=fbrq_mz));
set _mzrz;jzrq_mz1=DHMS(input(substr(jzrq_mz,1,10),yymmdd10.),0,0,input(substr(jzrq_mz,12,20),hhmmss.));
fbrq_mz1=MDY(substr(fbrq_mz,6,2),substr(fbrq_mz,9,2),substr(fbrq_mz,1,4));
drop jzrq_mz fbrq_mz;
format jzrq_mz1 datetime.fbrq_mz1 DATE9.;
label jzrq_mz1=“&mz.诊断日期” fbrq_mz1=“&mz.发病日期”;
run;
%end;
%else%if “&mz”=“网报”%then%do;
data &name.(rename=(jzrq_wb1=jzrq_wb));
set _mzrz;jzrq_wb1=DHMS(input(substr(jzrq_wb,1,10),yymmdd10.),0,0,input(substr(jzrq_wb,12,20),hhmmss.));
drop jzrq_wb;
format jzrq_wb1 datetime.fbrq_wb DATE9.;
label jzrq_wb1=“&mz.日期”;
run;
%end;
proc datasets;delete _:;run;quit;
%mend;
(2)数据的拼接、筛选和报表输出
%HIS宏程序能够输出医疗机构某时间段内单个传染病的迟报、漏报情况,同时输出传染病报卡与门诊日志项目的一致性情况,包含职业、年龄、现住址、性别、发病日期等。最后以Excel的形式展示详细信息[11],生成的Excel包含4个sheet,分别为迟报信息、漏报信息、准确报告信息、项目一致性信息。前3个sheet表格包含患者姓名、性别、年龄、医生姓名、诊断名称、诊断日期和网报日期等项目,能够进一步追溯原因,责任到人。自动生成的Word简略报告,包含报告率、及时率、一致率等评价指标。
%macro HIS(path=,disease=,type=,yymc=,date=,lb=,cb=,zq=,tot=);/*path是Excel汇总表存放路径,disease是核查传染病名称,type是传染病类别(甲类2小时内,乙丙类24小时内),yymc是医疗机构名称,date是查询时间段,lb是漏报,cb迟报,zq准确报告*/
proc sql;
create table &tot as
select mzrz.*,wbxx.*
from mzrz
left join wbxx
on mzrz.name_mz=wbxx.name_wb
where mzrz.zd_mz contains “&disease”
order by mzrz.name_mz,mzrz.jzrq_mz;
quit;/*首先按疾病名称筛选,再按姓名和就诊日期排序,最后以姓名进行数据集的横向拼接*/
data _null_;
if “%trim(%left(&type))”=“甲类” then call symput(“time”,7200);
else if “%trim(%left(&type))”^=“甲类” then call symput(“time”,86400);
run;/*甲乙丙类报告时限不同,分别对宏变量time赋值*/
data &lb &cb &zq;
set &tot;
second=intck(′second′,jzrq_mz,jzrq_wb);
by name_mz jzrq_mz;
if first.name_mz and first.jzrq_mz and name_wb=“ ” then do;/*first.var和last.var是SAS的两个临时变量,表示组内的第一个和最后一个变量。一般要跟在proc sort后,根据by后的变量使用*/
ps=“&disease.-漏报 ”;
keep yljg_name name_mz sex_mz age_mz jzrq_mz zd_mz ys_mz ks_mz jzrq_wb PS;
label PS=“备注”;
output &lb;
end;/*筛选出漏报情况*/
else if first.name_mz and first.jzrq_mz and second>&time then do;
ps=“&disease.-迟报”;
keep yljg_name name_mz sex_mz age_mz jzrq_mz zd_mz ys_mz ks_mz jzrq_wb PS;
label PS=“备注”;
output &cb;
end;/*筛选出迟报情况*/
else if first.name_mz and first.jzrq_mz then do;
ps=“&disease.-报告及时准确”;
keep yljg_name name_mz sex_mz age_mz jzrq_mz zd_mz ys_mz ks_mz jzrq_wb PS;
label PS=“备注”;
output &zq;
end;
run;
proc sql;
select count(*)into:num_lb from &lb;
select count(*)into:num_cb from &cb;
select count(*)into:num_yb from &zq;
quit;/*迟报人数、漏报人数赋予宏变量*/
data _&tot;
attrib job length=$40 age length=$40 xzz length=$40 sex length=$40 fbrq length=$40;
set &tot;
by name_mz jzrq_mz;
if first.name_mz and first.jzrq_mz and name_wb^=“ ”;
if job_mz^=job_wb then job=“不一致”;else if job_mz=job_wb then job=“一致”;
if age_mz^=age_wb then age=“不一致”;else if age_mz=age_wb then age=“一致”;
if xzz_mz^=xzz_wb then xzz=“不一致”;else if xzz_mz=xzz_wb then xzz=“一致”;
if sex_mz^=sex_wb then sex=“不一致”;else if sex_mz=sex_wb then sex=“一致”;
if fbrq_mz^=fbrq_wb then fbrq=“不一致”;else if fbrq_mz=fbrq_wb then fbrq=“一致”;
label job=“职业一致性” age=“年龄一致性” xzz=“现住址一致性” sex=“性别一致性” fbrq=“发病日期一致性”;
if job^=“一致” or age^=“一致” or xzz^=“一致” or sex^=“一致” or fbrq^=“一致”;
keep name_mz zd_wb job sex age xzz fbrq;
run;
proc sql;
select count(*)into:wtnum from _&tot;
select count(*)into:jobnum from _&tot where job^=“一致”;
select count(*)into:agenum from _&tot where age^=“一致”;
select count(*)into:xzznum from _&tot where xzz^=“一致”;
select count(*)into:sexnum from _&tot where sex^=“一致”;
select count(*)into:fbrqnum from _&tot where fbrq^=“一致”;
quit;
libname myexcel “&path&yymc.&date.期间&disease.报告情况.xls”;
data myexcel.“漏报%eval(&num_lb)例”n(dblabel=YES);set &lb;run;
data myexcel.“迟报%eval(&num_cb)例”n(dblabel=YES);set &cb;run;
data myexcel.“准确报告%eval(&num_yb)例”n(dblabel=YES);set &zq;run;
data myexcel.“项目一致性”n(dblabel=YES);set _&tot;run;
libname myexcel clear;
/*导出Excel含4个sheet,分别为迟报、漏报、准确报告及项目一致性情况*/
options nodate nonumber;
ods listing close;
ods rtf file=“&path&yymc.&date.期间&disease.报告情况.doc” bodytitle style=FONTS;
title “&yymc.&disease.报告情况”;
data _null_;
File print;
put “ &yymc.在&date.期间,共诊断%eval(&num_lb+&num_cb+&num_yb)例&disease.,其中漏报%eval(&num_lb)例,迟报%eval(&num_cb)例,准确及时报告%eval(&num_yb)例。报告率和及时率分别为%sysfunc(round(%sysevalf((&num_cb+&num_yb)/(&num_lb+&num_cb+&num_yb)*100),0.01))%NRSTR(%%和)%sysfunc(round(%sysevalf(&num_yb/(&num_cb+&num_yb)*100),0.01))%NRSTR(%%。)&yymc.在&date.期间,共网报%eval(&num_cb+&num_yb)例&disease.,网报信息一致%eval(&num_cb+&num_yb-&wtnum)人,一致率为%sysfunc(round(%sysevalf((&num_cb+&num_yb-&wtnum)/(&num_cb+&num_yb)*100),0.01))%NRSTR(%%。)其中,%eval(&jobnum)人职业与网报不一致,%eval(&agenum)人年龄与网报不一致,%eval(&xzznum)人现住址与网报不一致,%eval(&sexnum)人性别与网报不一致,%eval(&fbrqnum)人发病日期与网报不一致。详细情况见&yymc.&date.期间&disease.报告情况.xls”;
run;/*输出单个病种日志信息*/
ods rtf close;
ods listing;
%mend;
(3)自动核查多个传染病情况
%HISall宏程序则是针对医疗机构某时间段内的门诊日志,指定多个传染病病种进行迟报、漏报、一致性的分析,如手足口病、水痘、流行性腮腺炎,每个疾病输出一个Excel,包含迟报、漏报、准确报告及一致性情况四个sheet,最终将各病种Excel分类汇总。
%macro HISall(path1=,path2=,yymc=,date=);/*path1是存放待核查传染病病种的路径,path2是输出Excel报表的路径*/
proc import datafile=“&path1核查传染病名称.xls” out=_diseasename replace;sheet=“disease”;run;/*核查传染病名称Excel中包含疾病名称和类型,如手足口病,丙类*/
proc sql;select count(*)into:num_disease from _diseasename;
proc sql;
select disease,type into:dis1-:dis%trim(%left(&num_disease)),:typ1-:typ%trim(%left(&num_disease))from _diseasename;
quit;
data _lb _cb _zq _yz;set _null_;run;
%do i=1%to &num_disease;
%HIS(path=&path2,disease=&&dis&i,type=&&typ&i,yymc=&yymc,date=&date,lb=__lb&i,cb=__cb&i,zq=__zq&i,tot=_tot&i);/*调用单个传染病核查%HIS宏程序*/
……
/*部分报表输出程序与3(2)部分程序雷同,不再赘述*/
%mend;
实例与分析
通过HIS系统导出2015年4家医疗机构的门诊日志数据,中国疾病监测信息报告管理系统导出同期网报信息,数据资料仅用于验证程序,不代表真实情况。提交运行%label、%HISall宏程序(医疗机构A为例,病种选择手足口病、水痘和流行性腮腺炎):
%label(path=C:UsershpDesktop医疗机构A,mz=门诊,zl=门诊变量标签表,yymc=医疗机构A,name=mzrz);
%label(path=C:UsershpDesktop医疗机构A,mz=网报,zl=网报变量标签表,yymc=医疗机构A,name=wbxx);
%HISall(path1=C:UsershpDesktop医疗机构A,path2=C:UsershpDesktop医疗机构A报告情况,yymc=医疗机构A,date=2015.1-2015.12);
部分结果见表1~3,个人隐私信息采用*表示,项目一致率较低,未放入表1。选择各医疗机构中所有迟报、漏报情况进行人工核查,无明显错误。抽取20%的不一致项目、准确及时报告卡片进行人工核查,也无错误,可以认为该宏程序能够正确读取、整理、核查及输出所需结果。
表1 4家医疗机构2015年部分法定传染病的网报质量情况
*:未接诊流行性腮腺炎病人。
表2 医疗机构2015年部分法定传染病的迟报、漏报详细情况
表3 医疗机构2015年部分法定传染病的网报一致性情况
讨 论
本研究中宏程序的优点在于能够自动读取Excel文件中的病人诊疗信息、网报信息、待核查传染病病种,进而规范化数据格式,实现全自动的批量核查门诊日志中指定传染病的迟报、漏报、信息不一致情况,并计算评价指标,同时自动生成详细Excel报表。
该宏程序也存在一定的局限性:①医疗机构HIS系统和中国疾病监测信息报告管理系统导出的Excel文件变量名称均为中文,而SAS软件不能识别中文的变量名,会自动命名为_COL0、_COL1等,需在变量标签表中列出对应关系,如_COL2-name_mz-患者姓名,意思为将_COL2变量名称改成name_mz,标签为患者姓名。不同医疗机构HIS系统导出的Excel中变量名称顺序不一定相同,需要根据实际情况调整变量标签表中的blm列。②传染病监测报告质量有6个主要评价指标[6],本文仅实现了漏报率、迟报率和一致率的软件自动获得,而完整率涉及纸质报告卡,未能实现软件自动生成,逻辑准确率的逻辑关系较为复杂,待今后进一步完善。③法定传染病共有39种,少数病种的网报特性可能导致不适用此宏程序(如麻疹),因为该类疾病待实验室确诊后诊断名称及确诊日期可能会有改变,如疑似麻疹实验室确诊后修改为风疹或其他疾病。④SQL查询功能需要每一例观测有唯一的识别码,如果网报信息中出现两名不同病人的姓名且诊断名称相同的情况,可能会导致%HIS宏程序运行失败。⑤该宏程序针对同一病人多次就诊仅需初次报告的情况(如梅毒),已做特殊处理,不会对结果造成影响。但不适用于同一病人二次发病均需报告的情况,如同一病人一年内诊断并报告两次手足口病。
通过SAS软件编写宏程序可以在一定程度上为传染病信息报告质量的现状调查提供便利,简化工作流程。定期运行上述SAS宏程序对医疗机构门诊日志资料进行自动核查,实时了解各级医疗机构法定传染病网络直报工作完成质量,针对具体情况提出整改意见,及时掌握传染病的发病动态和流行趋势,为采取相应的预防和控制措施提供有效保障。
[1]尚晓鹏,吴晨,吴昊澄,等.浙江省医疗机构传染病报告质量调查.浙江预防医学,2015,27(6):635-637.
[2]郭青,苏雪梅,王晓风,等.2013年全国医疗机构法定传染病报告率调查分析.中华疾病控制杂志,2015,19(7):683-687.
[3]王晓宇,张志平.基于HIS系统的传染病报告管理的实践与体会.中国卫生产业,2016,13(1):105-107.
[4]高惠璇主编.SAS系统BaseSAS软件使用手册.第1版.北京:中国统计出版社,1997,160-173.
[5]SAS Institute Inc.SAS/STAT User′s Guide.Version 9.2.Cary,NC:SAS Institute Inc,2008:434-447.
[6]刘海霞,刘建地,杨建军,等.甘肃省传染病信息管理及报告质量调查分析.中国卫生统计,2013,30(5):734-735.
[7]魏永越,赵杨,柏建岭,等.SAS ODS及RTF标记语言在临床试验规范化统计报表输出中的应用.中国卫生统计,2010,27(4):428-430.
[8]屠海波.应用SQL语言进行数据查询与统计.中国卫生统计,2007,24(4):424-425.
[9]Burlew MM.SAS Macro Programming Made Easy.Second Edition.Cary,NC:SAS Institute Inc,2006:133-154.
[10]承晓华,王诗远,刘沛.一种可简化临床试验数据分析的SAS数据结构转换方法.中国卫生统计,2016,33(2):340-342.
[11]熊勇超,夏兰芳,宋渝丹,等.Tagsets.ExcelXP语句在SAS导出到Excel的方法应用.中国卫生统计,2016,33(2):336-338.
(责任编辑:刘 壮)
△通信作者:李杰,E-mail:lijie880531@sina.com