寧波市疾病預(yù)防控制中心(315010) 紀(jì) 威 張 濤 崔 軍
寧波市慢性病監(jiān)測(cè)工作覆蓋了四類主要慢性病——糖尿病、冠心病急性事件、腦卒中和惡性腫瘤的監(jiān)測(cè),該工作自2002年的監(jiān)測(cè)點(diǎn)醫(yī)院到2006年的省衛(wèi)生監(jiān)測(cè)區(qū),再至2009年慢性病網(wǎng)絡(luò)直報(bào)在全市醫(yī)療機(jī)構(gòu)開(kāi)展,隨著慢病患者逐年增多,發(fā)病報(bào)告數(shù)據(jù)也日益增長(zhǎng),因此如何對(duì)大量慢性病監(jiān)測(cè)數(shù)據(jù)進(jìn)行快速、準(zhǔn)確、有效地審核管理也成為困擾疾病預(yù)防控制機(jī)構(gòu)的一個(gè)亟待解決的難題。筆者以寧波市慢病監(jiān)測(cè)數(shù)據(jù)為例,應(yīng)用R軟件,提供一種簡(jiǎn)便的方式完成監(jiān)測(cè)數(shù)據(jù)的清理和統(tǒng)計(jì)工作,為更多監(jiān)測(cè)工作者提供了新的工作方法,也為R軟件的應(yīng)用提供了新思路。
R軟件像SAS和Stata等軟件一樣,主要使用命令行的方式處理數(shù)據(jù),語(yǔ)法簡(jiǎn)潔靈活、軟件開(kāi)源是R諸多亮點(diǎn)中的一粟。現(xiàn)在主流的數(shù)據(jù)庫(kù)以及數(shù)據(jù)分析軟件都可以方便地和R軟件實(shí)現(xiàn)對(duì)接和互調(diào),R也可以調(diào)用C、Java等高級(jí)語(yǔ)言,還可以根據(jù)使用者的需要定制擴(kuò)展包以完成特定的工作。
1.數(shù)據(jù)讀入
監(jiān)測(cè)中常見(jiàn)的為csv和Excel文件,其中csv是逗號(hào)分割分文本文件,可以通過(guò)
dat <- read.csv("文件路徑/文件名.csv")方式讀入并存儲(chǔ)在數(shù)據(jù)集dat中以便調(diào)用。例如筆者有名為“tnb330200.csv”的文件存放在E盤下,則使用
dat <- read.csv("E:/tnb330200.csv",as.is = TRUE)
其中read.csv是R中的一個(gè)函數(shù),用于讀入csv文件,as.is是這個(gè)函數(shù)中的一個(gè)選項(xiàng),用于防止在數(shù)據(jù)讀入時(shí)字符變量向因子類型的自動(dòng)轉(zhuǎn)換。
若數(shù)據(jù)為Excel文件,筆者推薦的方式是使用RODBC功能包中的odbcConnectExcel和sqlFetch函數(shù)。類似的,該包還提供了Access等數(shù)據(jù)文件的odbc接口。以E盤下的tnb330200.xls為例,使用方式如下:
require(RODBC)
chl <- odbcConnectExcel("E:/tnb330200.xls")
dat <- sqlFetch(chl,"Sheet1",as.is = TRUE)
odbcClose(chl)
require為加載包的命令,odbcConnectExcel建立與chl與Excel文件間的連接,sqlFetch讀取Excel文件中名為"Sheet1"的表格并存儲(chǔ)在數(shù)據(jù)集dat中,最后關(guān)閉這個(gè)連接。
在實(shí)際工作中,讀入的數(shù)據(jù)往往比較復(fù)雜,比如觀測(cè)個(gè)案可能含有缺失等情況,通常情況下對(duì)于缺失處為空的情況R會(huì)自動(dòng)將字符型的空白處理為空字符,而將數(shù)值型的空白處理為NA,“NA”是R中表示缺失的字符,可以用is.na來(lái)判斷。如果用戶在錄入數(shù)據(jù)時(shí),使用其他值例(如“9”“99”和“999”等)來(lái)代表缺失,則可以在讀入數(shù)據(jù)時(shí)使用參數(shù)na.strings=c(9,99,999)來(lái)指定缺失,也可以在數(shù)據(jù)讀入后將包含這些字符的位置替換為NA即可,替換方法可以參考本文的相關(guān)段落。
有時(shí)一個(gè)觀測(cè)可能占據(jù)多行,變量值中有可能包含分隔符等,對(duì)于前者,通??梢栽跀?shù)據(jù)讀入后使用專門的數(shù)據(jù)整理函數(shù)(例如reshape2包中的相關(guān)函數(shù))進(jìn)行處理;而對(duì)于后者,通??梢栽谧x入函數(shù)中使用相應(yīng)的參數(shù)加以解決,有興趣的讀者可以閱讀幫助文件和相關(guān)的文獻(xiàn)。
2.查找重復(fù)個(gè)案
糖尿病數(shù)據(jù)中包含患者的很多信息,例如姓名、性別、身份證號(hào)碼等,由于存在同一患者多次報(bào)告的情況,因此在分析前對(duì)數(shù)據(jù)進(jìn)行查重是有必要的。查重主要使用duplicated函數(shù),假設(shè)糖尿病數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)集dat中,假定姓名、性別、身份證號(hào)碼、住址、診斷名稱都相同的為重復(fù)個(gè)案,則找出這些重復(fù)個(gè)案可以使用如下方式:
dat[with(dat,duplicated(姓名,性別,身份證號(hào)碼,街道,糖尿病類型)),]
with函數(shù)指定所要操作的數(shù)據(jù)集,duplicated函數(shù)指定用于識(shí)別重復(fù)的變量名稱。相應(yīng)地,如果需要在數(shù)據(jù)集中刪除這些重復(fù)個(gè)案,只需使用:
dat[-with(dat,duplicated(姓名,性別,身份證號(hào)碼,街道,糖尿病類型)),]
3.查找含有缺失的個(gè)案
在慢性病報(bào)告中,個(gè)案信息的收集通常情況下是不完全的,有些重要信息(如身份證號(hào)碼、電話等)的缺失會(huì)對(duì)監(jiān)測(cè)查重和隨訪工作的順利進(jìn)行有較大影響,所以找出這些信息缺失的個(gè)案也顯得尤為重要,假設(shè)個(gè)案信息存儲(chǔ)在數(shù)據(jù)集dat中,則找出身份證號(hào)碼和電話缺失的個(gè)案可以使用如下方法:
dat[ind_idmiss | ind_phmiss,]
身份證號(hào)碼中通常會(huì)出現(xiàn)空格和空字符,所以需要先將空格替換為缺失值NA,再來(lái)查找缺失個(gè)案;電話號(hào)碼中除空格外還可能用“無(wú)”“未留”來(lái)表示缺失,因此需將包含該字的也替換為NA;is.na函數(shù)用于判斷一個(gè)字段中是否為NA值(即缺失值),這樣就獲得了身份證號(hào)碼和電話缺失的個(gè)案記錄,監(jiān)測(cè)工作者可以在此基礎(chǔ)上將相關(guān)信息予以補(bǔ)充。
4.查找數(shù)據(jù)中的邏輯錯(cuò)誤
對(duì)數(shù)據(jù)進(jìn)行邏輯審核是數(shù)據(jù)清洗中的重要一環(huán),找出有邏輯錯(cuò)誤的個(gè)案并及時(shí)訂正是保證數(shù)據(jù)質(zhì)量的重要手段,使用R軟件可以用簡(jiǎn)潔的語(yǔ)句找出邏輯錯(cuò)誤,以寧波市惡性腫瘤監(jiān)測(cè)數(shù)據(jù)為例,通常有如下邏輯錯(cuò)誤:錄入日期早于報(bào)卡日期、出生日期與身份證號(hào)碼中的信息不符、男性診斷有女性疾病(如宮頸癌)、女性診斷有男性疾病等,這里我們假設(shè)腫瘤存儲(chǔ)在數(shù)據(jù)集dat中,則找出這些個(gè)案可以使用如下方式:
attach(dat)
ind1 <- 錄入日期 < 報(bào)卡日期
ind2 <- substr(身份證號(hào)碼,7,14) != gsub("-","",出生日期)
#出生日期格式為"1966-01-01"
ind3 <- 腫瘤分類 == "宮頸癌" & 性別 == "男"
ind4 <- 腫瘤分類 == "前列腺癌" & 性別 == "女"
dat_logi <- dat[ind1 | ind2 | ind3 | ind4,]
detach(dat)
attach函數(shù)通常用于簡(jiǎn)化程序的書寫,其作用是將數(shù)據(jù)集dat加載到R的搜索路徑中,加載后只需輸入該數(shù)據(jù)集中的變量名稱即可直接調(diào)用這個(gè)變量;substr函數(shù)取出身份證號(hào)碼中生日所在的8位數(shù)字,gsub替換掉出生日期的橫線"-",然后將包含這4種邏輯錯(cuò)誤的個(gè)案統(tǒng)一存儲(chǔ)在數(shù)據(jù)集dat_logi中,最后detach從R的搜索路徑中卸載數(shù)據(jù)集dat。
5.將有邏輯錯(cuò)誤的個(gè)案寫入到文件
當(dāng)找出含有邏輯錯(cuò)誤的個(gè)案后,需要對(duì)個(gè)案進(jìn)行逐一核對(duì)以訂正錯(cuò)誤,此時(shí)通常需要將數(shù)據(jù)寫入到R之外以便核對(duì),將數(shù)據(jù)集寫入文件(以csv文件為例)可以使用:
write.csv(dat_logi,"E:/含有邏輯錯(cuò)誤的個(gè)案.csv",row.names = FALSE)
其中文件被寫到E盤下名為“含有邏輯錯(cuò)誤的個(gè)案”的csv文件,選項(xiàng)row.names = FALSE表示在寫入時(shí)不要寫入R自動(dòng)生成的個(gè)案行名。
本文中寥寥十幾行程序就完成了基本的數(shù)據(jù)查重和邏輯審核工作,R語(yǔ)言的簡(jiǎn)潔可見(jiàn)一斑,而且R語(yǔ)言中的函數(shù)使用簡(jiǎn)單直觀,便于使用者理解掌握。
此外,由于R軟件優(yōu)秀的可定制性,使用者可以編寫自己的軟件包以解決特定的問(wèn)題,筆者便在本文的基礎(chǔ)上編制了專門用于慢性病數(shù)據(jù)清理和統(tǒng)計(jì)的軟件包mbpkg,使用者可以不需要任何編程基礎(chǔ),只需簡(jiǎn)單地鼠標(biāo)點(diǎn)選便可輕松完成更為復(fù)雜的慢性病數(shù)據(jù)審核管理工作,在實(shí)際工作和科研過(guò)程中都有較好的推廣意義。有興趣的讀者可以根據(jù)研究?jī)?nèi)容編寫自己的軟件包。
參 考 文 獻(xiàn)
1. Brian Ripley.ODBC Connectivity.Department of Statistics,University of Oxford,2012,16:17.
2.Venables WN,Smith DM,the R Core Team.An Introduction to R,2012:27-28.