無錫市錫山區疾病預防控制中心(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