據(jù)庫入門實(shí)戰(zhàn)指南:免費(fèi)公開的流行病學(xué)數(shù)據(jù)挖掘方法)
做臨床、公衛(wèi)或者營養(yǎng)流行病方向的朋友應(yīng)該都繞不開NHANES數(shù)據(jù)庫。我最早接觸NHANES是在做膳食與代謝指標(biāo)關(guān)聯(lián)分析的時(shí)候當(dāng)時(shí)本來打算申請某機(jī)構(gòu)的數(shù)據(jù)結(jié)果流程走了兩個(gè)月還沒下來最后轉(zhuǎn)向NHANES從下載到跑出初步結(jié)果只用了一個(gè)下午。NHANES的全稱是National Health and Nutrition Examination Survey翻譯過來就是美國國家健康與營養(yǎng)調(diào)查由CDC下屬的國家衛(wèi)生統(tǒng)計(jì)中心NCHS負(fù)責(zé)執(zhí)行和維護(hù)。這個(gè)數(shù)據(jù)庫之所以在科研圈里幾乎“人手一份”核心原因就三個(gè)字免費(fèi)、公開、海量。它覆蓋了人口學(xué)、膳食、體檢、實(shí)驗(yàn)室檢驗(yàn)、內(nèi)分泌、環(huán)境暴露甚至心理健康等多個(gè)維度對于想做橫斷面研究、工具變量探索、方法學(xué)驗(yàn)證的人來說幾乎是不可替代的第一選擇。這篇內(nèi)容主要給剛接觸NHANES的朋友做個(gè)系統(tǒng)性梳理從數(shù)據(jù)庫的底層邏輯、官網(wǎng)怎么逛、文件怎么下載讀取一直到變量篩選、數(shù)據(jù)合并和常見坑一條線走完。我盡量少講虛的全是實(shí)際操作中驗(yàn)證過的東西適合醫(yī)學(xué)生、臨床醫(yī)生、公衛(wèi)研究者和數(shù)據(jù)分析師參照使用。1. NHANES是什么先摸清這個(gè)數(shù)據(jù)庫的家底1.1 從名字看本質(zhì)這不是一個(gè)簡單的“問卷庫”很多人第一次聽說NHANES以為它就是一個(gè)問卷數(shù)據(jù)庫這其實(shí)是一個(gè)比較大的誤解。NHANES不是單一的數(shù)據(jù)集而是一套復(fù)雜的、多維度、持續(xù)進(jìn)行的健康調(diào)查系統(tǒng)每一輪調(diào)查都同時(shí)收集訪談問卷、體格檢查、實(shí)驗(yàn)室檢測三類數(shù)據(jù)。說得直白一點(diǎn)一個(gè)人參加NHANES調(diào)查之后留下的記錄不止是“他回答了什么”還包括“他被測量了什么”和“他血液里測出了什么”。這種結(jié)構(gòu)對做數(shù)據(jù)分析的人來說是好事也是壞事。好事在于變量極其豐富從最基本的年齡性別到血常規(guī)、生化指標(biāo)、重金屬暴露、維生素水平、農(nóng)藥代謝物應(yīng)有盡有壞事在于你需要掌握不同模塊之間的關(guān)聯(lián)方式否則很容易在合并數(shù)據(jù)的時(shí)候把自己繞暈。NHANES從1960年代就開始做全國性的健康檢查1971年開始連續(xù)性的調(diào)查項(xiàng)目1999年起正式改成了連續(xù)進(jìn)行的調(diào)查計(jì)劃。也就是說從1999年到現(xiàn)在每個(gè)兩年為一個(gè)調(diào)查周期數(shù)據(jù)每兩年發(fā)布一次公開供全球研究者下載使用。這種“連續(xù)滾動(dòng)的橫斷面調(diào)查”設(shè)計(jì)讓它既能做單周期橫斷面分析也能通過合并多個(gè)周期來擴(kuò)大樣本量。1.2 數(shù)據(jù)分塊問卷、檢查、檢驗(yàn)三大模塊NHANES的數(shù)據(jù)可以從大體上拆成四個(gè)模塊對應(yīng)官網(wǎng)上不同的文件目錄。第一個(gè)是人口學(xué)模塊Demographics包含年齡、性別、種族、教育程度、婚姻狀況、收入比等重要的人口與社會經(jīng)濟(jì)變量。第二個(gè)是問卷模塊Questionnaire包含飲食攝入、吸煙飲酒、體力活動(dòng)、慢性病史、用藥情況、心理健康等大量自報(bào)信息。第三個(gè)是檢查模塊Examination包含身高、體重、腰圍、血壓、體脂率等由專業(yè)人員操作測得的體格指標(biāo)。第四個(gè)是實(shí)驗(yàn)室模塊Laboratory包含血常規(guī)、肝功能、腎功能、血脂、血糖、糖化血紅蛋白、激素、維生素、重金屬、環(huán)境化學(xué)物等生化檢測結(jié)果。這套模塊化設(shè)計(jì)的好處是邏輯清晰——你想用什么數(shù)據(jù)就去哪個(gè)目錄下面找但伴隨著的問題是一個(gè)分析往往需要同時(shí)用到好幾張表。比如你想研究“肥胖和高血脂的關(guān)系”至少要用到人口學(xué)表拿年齡性別、身體測量表拿BMI、實(shí)驗(yàn)室表拿總膽固醇和甘油三酯。三張表拿下來數(shù)據(jù)合并就不可避免。1.3 連續(xù)周期制度為什么用“兩年”作單位NHANES從1999年開始按兩年一個(gè)周期發(fā)布數(shù)據(jù)1999-2000是第一個(gè)周期2001-2002是第二個(gè)2003-2004是第三個(gè)依次類推。每個(gè)周期的文件名帶有一個(gè)固定的字母代號從A開始排1999-2000是A2001-2002是B2003-2004是C一路排下去。2015-2016是I2017-2018是J2017-2020是特殊的“P”周期新冠疫情導(dǎo)致調(diào)查中斷后整合發(fā)布的pre-pandemic數(shù)據(jù)。為什么強(qiáng)調(diào)這個(gè)字母代號因?yàn)橄螺d文件、寫讀取代碼、合并多周期數(shù)據(jù)時(shí)你都得靠它來認(rèn)文件。比如2015-2016周期的人口學(xué)文件就是DEMO_I.XPT身體測量文件是BMX_I.XPT總膽固醇文件是TCHOL_I.XPT后面這個(gè)“I”就是周期代號。記住這個(gè)規(guī)律你在官網(wǎng)找文件時(shí)基本不會迷路。兩年一個(gè)周期還有一個(gè)實(shí)際含義每個(gè)周期的樣本量大約是5000到10000人不等如果你做的是比較小眾的暴露變量或結(jié)局變量單周期樣本量可能不夠那就需要合并多個(gè)周期。但多周期合并會涉及到權(quán)重調(diào)整等問題這一塊后文會專門講。2. 從瀏覽器到數(shù)據(jù)文件NHANES官網(wǎng)應(yīng)該怎么逛2.1 官網(wǎng)入口與導(dǎo)航邏輯NHANES的數(shù)據(jù)官網(wǎng)是cdc.gov下的nchs/nhanes板塊不需要注冊賬號不需要機(jī)構(gòu)郵箱不需要審批流程直接就能訪問和下載。這個(gè)體驗(yàn)在公共衛(wèi)生數(shù)據(jù)圈里確實(shí)非常友好。首頁上最重要的入口叫做“Questionnaires, Datasets, and Related Documentation”也就是問卷、數(shù)據(jù)集及相關(guān)文檔的匯總頁面。點(diǎn)進(jìn)去之后你首先要選擇調(diào)查周期。官網(wǎng)上通常會列出1999-2000一直到最近的周期選完周期后就能看到該周期下所有的數(shù)據(jù)文件列表。早期周期1999-2000到2011-2012的頁面比較簡樸就是一個(gè)長長的文件列表近年周期2013-2014之后的頁面更偏數(shù)據(jù)庫風(fēng)格支持按模塊篩選、按關(guān)鍵詞查找變量還帶在線codebook預(yù)覽功能。不過無論頁面形態(tài)怎么變底層邏輯沒有變按周期選文件、按文件名認(rèn)模塊。2.2 核心下載頁面按模塊快速定位文件每個(gè)周期的數(shù)據(jù)文件頁面上文件名的前綴是有固定規(guī)律的掌握了規(guī)律就不需要一個(gè)個(gè)點(diǎn)開看描述。人口學(xué)模塊以DEMO開頭身體測量模塊以BMX或WHQ開頭飲食問卷以DR和DSQ開頭糖尿病問卷以DIQ開頭血壓相關(guān)以BPX開頭實(shí)驗(yàn)室模塊以比如TCHOL、TRIGLY、GLU、GHB、CBC等具體檢測項(xiàng)目命名。舉個(gè)例子如果你想做2015-2016周期的“BMI與血清總膽固醇關(guān)系”需要找的文件基本就是DEMO_I.XPT、BMX_I.XPT和TCHOL_I.XPT。文件名后面還可以點(diǎn)開“Doc”和“Codebook”分別查看問卷原文和變量字典。變量字典是接下來最常參考的文件。2.3 一個(gè)變量的完整文檔長什么樣下載一個(gè)變量之前我強(qiáng)烈建議先看它的Codebook也就是變量字典。點(diǎn)開任意一個(gè)文件的Codebook你會看到類似這樣的結(jié)構(gòu)每個(gè)變量的SAS標(biāo)簽名、英文全稱、數(shù)據(jù)類型、取值范圍、缺失值編碼以及樣本頻數(shù)分布。以總膽固醇變量LBXTC為例它在TCHOL_I.XPT里的定義很清晰變量名LBXTC標(biāo)簽“Total Cholesterol (mg/dL)”是一個(gè)連續(xù)型數(shù)值變量同時(shí)文件里還會列出有效樣本量、均值、標(biāo)準(zhǔn)差、分位數(shù)。旁邊通常還會附一個(gè)說明告訴你該變量是基于哪種檢測方法、在哪個(gè)實(shí)驗(yàn)室完成。對于做論文的人來說這部分信息可以直接引用到方法學(xué)部分。還有一類變量是分類變量比如種族變量RIDRETH1codebook會列出每一類的編碼和標(biāo)簽比如1代表Mexican American2代表Other Hispanic3代表Non-Hispanic White4代表Non-Hispanic Black。以后再跑回歸時(shí)記得把這些分類變量轉(zhuǎn)成因子不要直接當(dāng)連續(xù)變量丟進(jìn)模型。3. 實(shí)操第一關(guān)下載、讀取XPT文件并看懂?dāng)?shù)據(jù)結(jié)構(gòu)3.1 文件格式XPT與常見讀取方式NHANES數(shù)據(jù)文件的下載格式主要是XPT這是SAS的傳輸文件格式一個(gè)文件對應(yīng)一張數(shù)據(jù)表。XPT的好處是兼容性強(qiáng)SAS、R、Python、SPSS都能讀不需要額外購買軟件。我自己最常用的讀取工具是R語言中的haven包一行代碼就能把XPT讀進(jìn)來library(haven) demo - read_xpt(DEMO_I.XPT) bmx - read_xpt(BMX_I.XPT) tchol - read_xpt(TCHOL_I.XPT)如果用的是Python推薦用pyreadstat庫import pandas as pd import pyreadstat demo, meta pyreadstat.read_xport(DEMO_I.XPT) bmx, meta pyreadstat.read_xport(BMX_I.XPT) tchol, meta pyreadstat.read_xport(TCHOL_I.XPT)SAS用戶直接用proc import就能讀取proc import datafileDEMO_I.XPT outdemo dbmsxport replace; run;讀進(jìn)來之后建議先對一下行列數(shù)DEMO文件的每一行代表一個(gè)受檢者行數(shù)應(yīng)該等于該周期總樣本量但BMX和TCHOL這類只有體檢或?qū)嶒?yàn)室亞樣本的文件行數(shù)會比DEMO少。這個(gè)差異很重要因?yàn)樗苯佑绊懩愫竺婧喜⒈淼倪壿嫛?.2 樣本量與權(quán)重第一次用NHANES最容易翻車的地方NHANES不是簡單隨機(jī)抽樣而是采用了復(fù)雜的分層多階段概率抽樣設(shè)計(jì)。為了保證特定人群比如老年人、非裔美國人、西語裔人群的分析可靠性抽樣時(shí)對部分亞群做了過度抽樣。因此直接用原始樣本來算全國代表性估計(jì)結(jié)果是偏的必須使用權(quán)重。打開DEMO文件后你會看到好幾列權(quán)重變量最常碰到的有三個(gè)WTPFQX面訪權(quán)重、WTMEC體檢權(quán)重、WTMEC2YR兩年周期體檢權(quán)重。特別需要注意的是如果你分析的變量來自實(shí)驗(yàn)室檢測或體格檢查對應(yīng)的分析樣本是“MEC檢查子樣本”這時(shí)候必須使用MEC權(quán)重而不是面訪權(quán)重。對于單周期分析直接用WTMEC2YR就是推薦做法。如果你合并了多個(gè)周期比如把2015-2016和2017-2018兩個(gè)周期合并就不能簡單地把兩個(gè)WTMEC2YR相加而是要根據(jù)新的合并樣本構(gòu)造分析權(quán)重。這個(gè)問題很常見后續(xù)我單獨(dú)寫一段展開。3.3 合并多張表的正確姿勢一切以SEQN為錨點(diǎn)NHANES各張表之間通過一個(gè)唯一的受檢者編號SEQN關(guān)聯(lián)類似關(guān)系數(shù)據(jù)庫里的主鍵。每一行數(shù)據(jù)的SEQN在整個(gè)調(diào)查周期內(nèi)是唯一的你只需要用SEQN做合并即可。R里用dplyr的inner_join或left_join都行。我個(gè)人的經(jīng)驗(yàn)是先確定你的分析人群優(yōu)先以DEMO為主表做left join把相關(guān)變量逐一接進(jìn)來而不是把所有表做笛卡爾積式的大合并。這樣既減少內(nèi)存壓力也更容易追蹤樣本量變化。merged - demo %% select(SEQN, RIAGENDR, RIDAGEYR, RIDRETH1, WTMEC2YR) %% left_join(select(bmx, SEQN, BMXBMI), by SEQN) %% left_join(select(tchol, SEQN, LBXTC), by SEQN)這里有幾個(gè)細(xì)節(jié)要提醒。一是老版本的文件中變量可能用大寫讀進(jìn)R后要統(tǒng)一變量名大小寫二是部分文件里的SEQN是數(shù)值型另一部分可能是字符型合并前最好統(tǒng)一類型否則匹配不上三是空洞值非常多尤其是實(shí)驗(yàn)室變量很多受檢者沒有抽血或者沒有檢測結(jié)果這種缺失是正常的關(guān)鍵是要在論文里寫明最終納入樣本量。4. 變量篩選與數(shù)據(jù)清洗從“有數(shù)據(jù)”到“能分析”4.1 用Codebook確定變量取值范圍新手拿到數(shù)據(jù)后最常見的操作就是把變量一股腦丟進(jìn)模型然后發(fā)現(xiàn)結(jié)果出現(xiàn)奇怪的系數(shù)或者報(bào)錯(cuò)。其實(shí)大部分問題在Codebook階段就能規(guī)避。比如你想用“糖尿病問卷中的確診情況”這個(gè)變量codebook里通常會給出三類編碼1代表有糖尿病2代表沒有3代表臨界狀態(tài)7代表拒絕回答9代表不知道。分析前你至少要做兩件事把7和9這類非有效回答設(shè)為缺失把1和2明確轉(zhuǎn)成二進(jìn)制變量。很多人忽略了一個(gè)細(xì)節(jié)就是某些變量在特定周期內(nèi)的編碼并不完全一致比如同一個(gè)“教育程度”變量2011-2012周期和2015-2016周期的分類可能不同跨周期合并時(shí)必須先統(tǒng)一編碼否則結(jié)果完全不可比。4.2 幾類必須處理的編碼細(xì)節(jié)NHANES數(shù)據(jù)里的“缺失”并不只有一種表現(xiàn)形式。數(shù)值型變量通常用“.”表示缺失但分類變量里常常用7、9這類代碼表示拒絕回答或不知道實(shí)驗(yàn)室檢測值有時(shí)候會因?yàn)榈陀跈z測下限被標(biāo)記為某個(gè)固定值比如“LOD”或者“LLOQ”這類值在codebook里會專門說明需要根據(jù)說明決定是保留還是轉(zhuǎn)為缺失。連續(xù)性變量還有一個(gè)常見坑單位不一致。比如血糖變量有的周期以mg/dL為單位有的可能同時(shí)給出SI單位mmol/L總膽固醇變量也有傳統(tǒng)單位和國際單位兩套??缰芷诤喜⒒蛘邊⒖嘉墨I(xiàn)做閾值判斷時(shí)必須把單位統(tǒng)一。這個(gè)坑我踩過不止一次進(jìn)回歸之前把summary跑一遍看到異常范圍值就要警覺。4.3 樣本量估計(jì)與連續(xù)性變量的合并期數(shù)做NHANES數(shù)據(jù)分析樣本量估算往往不是按常規(guī)的檢驗(yàn)效能公式而是受限于“某變量有多少非缺失值”。比如你想研究“尿中某重金屬與血脂的關(guān)聯(lián)”重金屬檢測是隨機(jī)抽取的亞樣本可能整個(gè)周期只有1500人左右有檢測值按暴露四分位分組后每組不到400人再加協(xié)變量后模型可能就很不穩(wěn)定。這時(shí)候通常的做法是合并多個(gè)周期。合并周期不是簡單把文件拼接起來核心問題是權(quán)重。比較粗略的做法是把每個(gè)周期的WTMEC2YR除以合并周期數(shù)當(dāng)作近似的新權(quán)重學(xué)術(shù)上更嚴(yán)謹(jǐn)?shù)淖龇ㄊ遣殚哊CHS發(fā)布的權(quán)重構(gòu)造指南或者找專門的復(fù)權(quán)方法文獻(xiàn)。實(shí)操上我在合并2013-2014和2015-2016兩個(gè)周期時(shí)會先分別提取兩個(gè)周期各自的目標(biāo)變量統(tǒng)一變量名和編碼再按SEQN上下堆疊最后把新權(quán)重列設(shè)為WTMEC2YR/2。這樣做近似可接受但如果審稿人較真權(quán)重構(gòu)造還是要在方法部分寫清楚。5. NHANES使用避坑指南我替你們踩過的坑5.1 權(quán)重怎么選Interview Weight和MEC Weight的差別這是NHANES初學(xué)者最常搞混的地方。簡單說面訪權(quán)重WTPFQX適用于純問卷數(shù)據(jù)體檢權(quán)重WTMEC適用于所有在移動(dòng)檢查中心完成的測量數(shù)據(jù)比如血壓、身高體重、實(shí)驗(yàn)室檢測。大部分臨床指標(biāo)分析用的都是MEC權(quán)重因?yàn)槌檠腕w格測量都在MEC里完成。我見過不少帖子直接拿面訪權(quán)重分析血脂數(shù)據(jù)結(jié)果估計(jì)值和官方報(bào)告差了一大截。還有一個(gè)細(xì)節(jié)是空腹亞樣本權(quán)重WTSAF2YR適用于空腹血糖、胰島素等需要空腹抽血的項(xiàng)目。你要分析空腹血糖就必須用這個(gè)權(quán)重而不是普通的WTMEC2YR。文件說明里會明確標(biāo)注“Use WTSAF2YR for fasting subsample”這一行字一定要看到。5.2 缺失值背后有講究同樣是缺失原因卻可以完全不同。NHANES里的缺失可能是“沒有參加體檢”“參加了體檢但沒抽血”“抽了血但檢測失敗”“檢測結(jié)果低于檢測下限”等多種情況。不同原因?qū)?yīng)的處理方式是不同的。最典型的是“低于檢測下限”這種情況常見于重金屬、維生素D、部分環(huán)境化學(xué)物。有的周期直接把檢測下限值填進(jìn)去有的周期填的是某個(gè)推導(dǎo)值還有的周期會在標(biāo)記變量中告知你比例。如果你直接忽略這些信息做log轉(zhuǎn)換得到的分布可能嚴(yán)重失真。對這個(gè)問題的處理沒有統(tǒng)一標(biāo)準(zhǔn)但至少你要在方法部分交代清楚你是如何對待這些非典型值的。我個(gè)人的習(xí)慣是先看codebook里的說明再看變量分布最后決定是保留原值、轉(zhuǎn)成LOD/2還是做敏感性分析。5.3 不同周期的變量名與編碼未必相同這是跨周期合并的另一個(gè)大坑。NHANES的變量命名總體有連續(xù)性但同一個(gè)變量在不同周期的文件里可能存在細(xì)節(jié)差異。比如某個(gè)變量在2011-2012周期叫DID040到了2013-2014可能變成DID050某個(gè)分類變量的編碼在2009-2010和2011-2012之間也可能調(diào)整過選項(xiàng)。所以跨周期合并時(shí)最穩(wěn)妥的做法是先把每個(gè)周期的目標(biāo)變量單獨(dú)抽出來逐一核對codebook中的標(biāo)簽、類型、取值編碼、單位全部統(tǒng)一后再合并。不要抱著“變量名看著差不多就直接rbind”的心態(tài)不然跑出來的結(jié)果事后根本沒法解釋。下面是幾個(gè)我用NHANES過程中遇到的典型問題整理成一張速查表方便大家對照現(xiàn)象可能原因處理方式讀取XPT文件報(bào)錯(cuò)文件下載不完整或版本過舊重新下載R中用haven、Python中用pyreadstat重新讀取合并后樣本量驟減到幾百用inner_join把沒有實(shí)驗(yàn)室結(jié)果的樣本全丟掉了明確分析目標(biāo)和暴露/結(jié)局變量來源合理選擇left_join或inner_join加權(quán)后人群估計(jì)和官方報(bào)告差很多權(quán)重選錯(cuò)比如該用WTMEC用了WTPFQX回到codebook檢查建議權(quán)重特別是亞樣本變量連續(xù)變量范圍異常單位不一致比如mg/dL與mmol/L混用核對codebook中的單位說明統(tǒng)一后再分析分類變量回歸突然報(bào)錯(cuò)編碼里有7、9等無效值先將拒絕回答/不知道編碼設(shè)為缺失兩個(gè)周期合并后分布出現(xiàn)斷層兩周期變量編碼或檢測方法不完全一致逐周期核對變量標(biāo)簽與取值必要時(shí)做敏感性分析第6個(gè)問題值得再強(qiáng)調(diào)一下NHANES不同周期的實(shí)驗(yàn)室檢測方法可能更新過即使變量名一樣數(shù)值的可比性也可能受影響。比如某段時(shí)期的血糖檢測從酶法換成了己糖激酶法雖然總體偏差不大但嚴(yán)謹(jǐn)?shù)难芯慷紤?yīng)該把“檢測方法”作為敏感因素討論。寫到這里我想到一個(gè)很實(shí)際的小建議第一次用NHANES做完整分析最好先拿一個(gè)已經(jīng)發(fā)表的目標(biāo)變量組合練手比如“BMI和總膽固醇”從官方文檔里找到他們的分析規(guī)范努力復(fù)現(xiàn)官方表格里的人群均值。這個(gè)過程能逼你把權(quán)重、合并、缺失處理這些基本功全部過一遍比看十篇教程都管用。我當(dāng)初就是這么入門的復(fù)現(xiàn)出一張官方表格時(shí)的那種踏實(shí)感是刷代碼永遠(yuǎn)體會不到的。后面我會繼續(xù)寫NHANES的進(jìn)階主題包括多周期合并的權(quán)重構(gòu)造細(xì)節(jié)、常見研究設(shè)計(jì)怎么選樣本、以及如何把結(jié)果整理成符合論文要求的描述性表格。