進階已經雙重審閱,尚未人工抽查

條件式邏輯迴歸

配對之後為什麼不能用一般邏輯迴歸、strata() 到底在條件掉什麼、把配對變項放回模型會發生什麼事(答案是靜默地什麼都不發生),以及 1:1 配對時它與 McNemar 檢定的四個數值關係。

這個模型在解決什麼問題

配對(matching)是設計階段用來對付干擾的手段。做法是替每個 case 挑一或多個在指定變項上 (年齡、性別、就診年份、同一家醫院)與他相同或相近的 control,讓那些變項在設計上就不可能造成偏差。

但配對是一個要付利息的決定。 資料一旦配對,各個配對組(matched set)內部的人就不再彼此獨立, 而一般邏輯迴歸假設全部觀察值獨立。 把配對好的資料丟進 glm(..., family = binomial),等於把配對這件事整個丟掉。

條件式邏輯迴歸(conditional logistic regression)的做法是:只在配對組內部比較, 不讓不同組的人互相比較。技術上是把每一組自己的截距(也就是「這一組整體有多容易成為 case」) 從概似函數裡條件掉——這也是它叫「條件式」的原因。

一個有 MM 個 control 的配對組,對概似函數的貢獻是「這一組裡偏偏是這個人成為 case」的機率:

Li(β)=exp(βxi,case)jset iexp(βxij)L_i(\beta) = \frac{\exp(\beta^{\top} x_{i,\text{case}})} {\displaystyle\sum_{j \in \text{set } i} \exp(\beta^{\top} x_{ij})}

這一條式子把本頁後面三件事全部解釋掉了,值得先記住它長什麼樣子:分子只有 case, 分母是整組人,而組別本身完全沒有出現在式子裡

這一頁的例子

datasets::infert 是一份繼發性不孕症的配對病例對照研究,隨 R 本體一起出貨,不必安裝任何套件。 248 列、83 個配對組、每組恰好一個 case, 配對變項是年齡、產次與教育程度。暴露是自發性流產(spontaneous)與人工流產(induced)的次數

同一份資料也是病例對照研究那一章的例子。 那一章講的是設計本身;這一頁只講模型。

library(survival)
data(infert)

# 正確的模型:分層項就是配對組
cond <- clogit(case ~ spontaneous + induced + strata(stratum), data = infert)
summary(cond)

# 錯誤的模型:右邊完全一樣,只是把配對丟掉
naive <- glm(case ~ spontaneous + induced, data = infert, family = binomial)
exp(cbind(OR = coef(naive), confint.default(naive)))

# 把配對變項放回模型,看看會發生什麼事
clogit(case ~ spontaneous + induced + age + parity + strata(stratum), data = infert)

驗證環境:R 4.6.0 + survival 3.8.6。clogit() 是 survival 套件的函式,內部呼叫的是 coxph(),所以報表看起來會像存活分析——這是實作方式,不是筆誤。

忽略配對會發生什麼事

兩個模型的右邊一模一樣,唯一的差別是有沒有 strata(stratum)。 這樣比較才乾淨:任何差異都只能歸給「有沒有尊重配對」,不會混進「多放了一個共變項」。

森林圖,橫軸是對數尺度的勝算比,垂直虛線畫在 1。四條估計由上而下:自發性流產的條件式估計 7.29(3.65–14.54),藍色方塊;同一個變項忽略配對的估計 3.31(2.19–5.01),紅色三角形,明顯落在藍色方塊的左邊、也就是更靠近 1 的那一側;人工流產的條件式估計 4.09(2.02–8.30),藍色方塊;同一個變項忽略配對的估計 1.52(1.02–2.27),紅色三角形,同樣落在左邊,信賴區間下界幾乎貼著 1。兩組對照的方向一致:忽略配對的估計都比條件式估計更靠近 1。
同一份資料、同樣的右手邊,唯一的差別是有沒有分層項。忽略配對的估計(三角形)在兩個變項上都更靠近 1。產圖腳本 figures/scripts/B2-10-conditional-logistic.R
變項條件式 OR忽略配對 OR倍數條件式 SE忽略配對 SE
自發性流產次數(spontaneous7.2853.3112.200.3520.212
人工流產次數(induced4.0921.5192.690.3610.206

自發性流產的 OR 從條件式的 7.285 掉到 3.311,差了一倍以上,而且是往 1 的方向掉。 人工流產同樣往 1 掉(4.092 → 1.519)。 這個方向不是巧合:配對讓 case 與 control 在配對變項上長得像, 如果把那些人混在一起當成獨立樣本比較,暴露與結果的關聯就會被稀釋。

strata() 到底在做什麼

回到上面那條概似函數。把它看成一個比賽:組裡每個人依 exp(βx)\exp(\beta^{\top}x) 拿到一個分數, 式子問的是「分數這樣分配之下,偏偏是 case 那個人中選的機率」。

如果一整組人的暴露完全相同,每個人的分數就一樣,那個機率永遠是 1/(M+1)1/(M+1), 不管 β\beta 是多少。 這樣的組對概似函數是一個常數,對估計的貢獻是 0,不是「很少」

這件事可以直接量。本頁主模型spontaneous + induced,兩個都是次數)底下, 一組要完全沒有貢獻,條件是組內每個人的兩個次數都一樣。 83 個配對組裡有 7 組符合, 剩下 76 組 (228 列)才帶得動估計。

把那 7 組整個刪掉再配一次

變項全部 83 組的係數只用 76 組的係數全部組的 SE只用那些組的 SE
自發性流產次數1.9858761.9858760.35240.3524
人工流產次數1.4090121.4090120.36070.3607

係數與標準誤的最大差距分別是 1.1e-15 與 5.6e-16——那是浮點數的機器精度,不是真的差異。 那 7 組完全沒有進到答案裡

下面這張圖畫的不是主模型,而是一個看得懂的簡化版: clogit(case ~ spont_any + strata(stratum))。它和主模型差兩件事—— 暴露壓成二元(有過/沒有過自發性流產),而且 induced 不在模型裡。 條件放寬了,符合「整組相同」的組數就多了: 28 組整組相同、 55 組有變異。 道理一樣,只是這個版本畫得出來(一格塗色或不塗色),而次數畫不出來。 在這個簡化模型上,全部組與只用有變異的組配出來的係數都是 1.653873

兩欄圖。左欄畫出 infert 裡六個真實的配對組,每組一列,一個 case 方框加兩個 control 方框;方框有填色代表那個人有過至少一次自發性流產。前三組(編號 1、4、5)組內的填色不一致,右側標註 informative;後三組(編號 2、3、6)整組填色一致——其中兩組全部沒填色、一組全部填色——右側以淡色標註 cancels out。左欄下方寫著 55 of 83 sets vary within themselves,以及全部組配出的係數 1.6539 與只用有變異的組配出的係數 1.6539,兩個數字相同。右欄是 1:1 配對後的 2×2 表,四格分別是雙方都暴露 17、只有 case 暴露 38、只有 control 暴露 8、雙方都沒暴露 20;只有對角線以外的兩格被加粗高亮。下方列出 b 除以 c 等於 4.750、clogit OR 等於 4.750、未校正 McNemar 統計量 19.565、clogit score 檢定 19.565、以及有連續性校正的 McNemar 18.283。
左:組內暴露一致的配對組對估計的貢獻是零,把它們拿掉係數一個小數位都不動。右:1:1 配對時,只有不一致的兩格進得了估計。產圖腳本 figures/scripts/B2-10-conditional-logistic.R

配對變項不可以再放進模型

這是配對分析最容易犯、也最難自己發現的錯。看看把配對變項加回去會怎樣:

加進模型的變項它自己的係數它的標準誤spontaneous 的係數配適後 log-likelihoodR 講了什麼
ageNA01.98587552-64.20223692(什麼都沒講)
parityNA01.98587552-64.20223692(什麼都沒講)
educationNA01.98587552-64.20223692(什麼都沒講)
age + parity + educationNA01.98587552-64.20223692(什麼都沒講)

沒有加任何配對變項時,spontaneous 的係數是 1.98587552, log-likelihood 是 -64.20223692。 上表每一列都與它完全相同:最大變化量是 0(係數)與 0(log-likelihood)。 不是「接近」,是 0。

原因還是那條概似函數。配對變項在組內是常數,exp(βx)\exp(\beta^{\top}x) 裡屬於它的那一項 在分子與分母同時出現、同時約掉,所以它根本沒有辦法改變任何東西。 資料裡沒有任何資訊可以用來估它。

1:1 配對時,它與 McNemar 的關係

配對成 1:1(每個 case 一個 control)而暴露是二元時,條件式邏輯迴歸會退化成一個手算得出來的東西。

把每一對按「case 有沒有暴露」乘「control 有沒有暴露」分成四格:

control 有暴露control 沒暴露
case 有暴露17(一致)38(b
case 沒暴露8(c20(一致)

對角線上那 37 對,兩個人的暴露一樣, 依上一節的道理對估計沒有貢獻。剩下 46 對不一致對(discordant pairs) 就是全部的資訊,而條件 OR 正好是這兩格的比值:

OR^條件=bc,χMcNemar2=(bc)2b+c\widehat{\mathrm{OR}}_{\text{條件}} = \frac{b}{c}, \qquad \chi^{2}_{\text{McNemar}} = \frac{(b-c)^{2}}{b+c}

實際跑出來:38 除以 8 等於 4.750, 而 clogit() 給的 OR 是 4.750。 兩者相差 1.8e-8, 那是最佳化演算法的收斂容差,不是真的差異。

反過來說,這也是為什麼多數情況下不該只做 McNemar。 McNemar 只吃一個二元暴露,沒有辦法校正其他變項,也處理不了 1:M 配對或連續型暴露。 條件式邏輯迴歸做得到全部這些,而在 McNemar 適用的那個特例上又給出同一個答案。

常見誤用

誤用為什麼錯
配對資料用一般邏輯迴歸配對組內不獨立;估計往 1 偏,而 p 值不會警告你
用 p 值變化判斷有沒有漏掉配對p 值兩個方向都可能動,看設計文件才可靠
把配對變項當共變項放進模型組內是常數,係數回 NA 而且完全沒有警告
看到那一欄是 NA 就把 strata() 拿掉退回錯誤模型;正確做法是把配對變項移出模型
沒有檢查 coef() 有沒有 NA 就報表這是唯一會提醒你變項被丟掉的地方
以為配對組數越多、配得越緊越好過度配對會讓組內暴露也一致,那些組貢獻是零
用列數當樣本量講檢定力有效資訊量是「組內有變異」的組數
說「條件式邏輯迴歸等於 McNemar」而不指名檢定未校正 McNemar 才等於 score 檢定,預設是有校正的
只報 McNemar 就結束校正不了其他變項,也處理不了 1:M 與連續暴露
把配對病例對照的 OR 當成 RR 讀病例對照的分母是研究者挑的,見病例對照研究
把 1:M 的資料硬拆成 1:1 來做 McNemar丟掉其他 control 的資訊;直接用 clogit() 即可
配對變項在分析階段「再校正一次」以求保險不會更保險,只會讓報表出現看不懂的空欄

重跑本頁的所有數字

/opt/homebrew/bin/Rscript figures/scripts/B2-10-conditional-logistic.R

讀讀看這張圖

答案取自產生本頁圖表的同一份統計輸出,不是另外打上去的。

同一份配對資料,conditional logistic 與忽略配對的一般 logistic 給出不同的 odds ratio。忽略配對做了什麼?

看答案與解析

正確答案: 得到 7.29——這是 conditional 模型的值,忽略配對後估計會被拉低到不及它的一半

conditional 模型給 7.29,忽略配對的一般 logistic 給 3.31,掉了一半以上。忽略配對不是「少校正一點」而已:配對變項決定了誰會被選進來當對照,忽略它等於忽略選案機制,估計因此被往一的方向拉。4.09 是 conditional 模型裡另一項(每多一次人工流產),不是同一個對比。在配對研究裡,配對是設計的一部分,分析必須跟著它走。

83 個配對組裡,有 7 組組內每個人的暴露完全相同。它們對 conditional logistic 的估計有什麼貢獻?

看答案與解析

正確答案: 這 7 組完全沒有貢獻,條件概似對它們是一個常數

組內暴露完全一致的 7 組對條件概似只貢獻一個常數,等於不存在——conditional logistic 只用得上組內有差異的 76 組。83 是總組數,把它當成有效樣本數會高估這份資料能支撐多少參數。這是為什麼「我有兩百多筆資料」在配對研究裡不是有效樣本數的說法:該數的是有差異的組,不是列。

把每組取一個 case 與一個 control 湊成 1:1 配對之後,McNemar 檢定實際用到的是哪些配對?

看答案與解析

正確答案: 不一致配對,共 46 對——只有兩人暴露不同的配對帶得動估計

McNemar 檢定與由配對算出來的 odds ratio 都只用得上不一致的 46 對。一致的 37 對再多,對估計值一點影響也沒有,它們只是讓樣本數看起來比較大——檢定力取決於不一致配對的數目,不是總配對數 83。看到配對研究報出一個很大的 n,要問的是其中有多少對是不一致的。

素材來源與授權

本頁為原創內容

回報內容問題

這個站的統計內容由 AI 撰寫、AI 互審,人工只做抽查。你看得出來的錯,我們不一定看得出來。

寫得越具體越修得動,例如哪一句話跟哪本教科書/哪篇論文的說法不一致。

留了才回得了信;不留也會看。

一併送出的資訊

這些是自動帶上的,每一項都可以取消。