ทำไม Logistic และ Conditional Logistic Regression จึงให้ Odds Ratio ต่างกัน?

Clinical Epidemiology ResearchMethodology and Research Design THUniqcret doctor knowledges TH
ทำไม Logistic และ Conditional Logistic Regression จึงให้ Odds Ratio ต่างกัน?
On this page

Read the English version

บทคัดย่อ

Ordinary Logistic Regression และ Conditional Logistic Regression อาจให้ Odds Ratio ต่างกันมากจากข้อมูลชุดเดียวกัน เพราะสองโมเดลตอบคำถามต่างกัน ใน Matched Pairs 20 คู่จากการศึกษาแบบ Nested Case-Control เรื่อง Inadequate Antenatal Care กับ Neonatal Morbidity ภายใน 28 วัน Ordinary Logistic Regression ได้ OR = 1.83 และ Conditional Logistic Regression ได้ OR = 4.00 Control แต่ละรายสุ่มด้วย Risk-Set Sampling จากทารกที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลาที่ Case ของมันเกิด Outcome Design นี้จึงถามคำถามภายใน Set การรวม 40 แถวเข้าด้วยกันเปรียบเทียบ Case ทั้งหมดกับ Control ทั้งหมด: (12/8)/(9/11) = 1.83 ส่วนการวิเคราะห์ภายใน Set เหลือเพียง 5 Discordant Pairs ที่ให้ข้อมูลเกี่ยวกับ Exposure: 4/1 = 4.00 ซึ่งไม่แม่นยำจนช่วงเชื่อมั่น 95% กว้างตั้งแต่ 0.45 ถึง 35.79 ภายใต้การสุ่มที่เหมาะสม Matched OR ประมาณ Hazard Ratio ของ Cox ไม่ใช่ Risk Ratio บทความนี้คำนวณค่าประมาณทั้งสองด้วยมือ แสดงที่มาของ Conditional Likelihood เชื่อม clogit กับ Cox Regression และทำซ้ำทั้งสองโมเดลใน Stata


ภาพสรุป ตัวอย่างคำนวณด้วยมือ: Matched Pairs ชุดเดียว สองโมเดล Odds Ratio สองค่า

Matched Pairs ชุดเดียวกัน แต่ได้ Odds Ratio สองค่า: 1.83 และ 4.00

ทีมวิจัยด้านทารกแรกเกิดทีมหนึ่งต้องการทราบว่า Inadequate Antenatal Care (ANC) คือการฝากครรภ์ที่น้อยเกินไปหรือเริ่มช้าเกินไป มีความสัมพันธ์กับการเกิด Neonatal Morbidity ภายใน 28 วันหลังคลอดหรือไม่

ทีมมีข้อมูล Matched Case-Control จำนวน 20 คู่ และทดลองวิเคราะห์ด้วยสองวิธี

ทั้งสองโมเดลใช้ข้อมูลเดียวกัน Exposure เดียวกัน และ Outcome เดียวกัน แต่กลับให้ผลลัพธ์ต่างกันอย่างชัดเจน

คำถามสำคัญคือ เหตุใดจึงเกิดความแตกต่างนี้ และควรเชื่อผลลัพธ์จากโมเดลใด

การตอบคำถามนี้ต้องเริ่มจาก Study Design ไม่ใช่จากสมการทางสถิติ ข้อมูล 20 คู่ที่ใช้ตลอดบทความเป็นตัวอย่างที่สร้างขึ้นเพื่อให้เห็นความแตกต่างของสองโมเดล ไม่ใช่ข้อมูลจริงจากหน่วยงานใด

เริ่มจาก Study Design: Risk-Set Sampling

สมมติว่าเราติดตามทารกตั้งแต่แรกเกิดจนถึงอายุ 28 วัน โดยสนใจ Time to First Composite Morbidity Event คือเวลาจนถึงภาวะแทรกซ้อนครั้งแรกในกลุ่มภาวะแทรกซ้อนของทารกแรกเกิดที่กำหนดไว้ล่วงหน้า

เมื่อทารกคนหนึ่งเกิด Outcome เช่น ณ วันที่ 5 หลังคลอด ทารกคนนั้นจะถูกจัดเป็น Case

จากนั้นสุ่ม Control จากทารกที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลาที่ Case เกิดเหตุการณ์ คือทารกที่ยังไม่เกิด Outcome การสุ่ม Control แบบนี้เรียกว่า Risk-Set Sampling และทารกที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลานั้นรวมกันเป็น Risk Set ของ Case รายนั้น [1] บทความแยกเรื่องการเลือก Control เปรียบเทียบวิธีนี้กับวิธีอื่น

ตัวอย่างเช่น Case หนึ่งรายกับ Control ของมันอาจเป็นดังนี้

ทารก A และ B อยู่ใน Risk Set เดียวกัน เพราะทั้งคู่ยังมีโอกาสเกิด Outcome จนถึงเวลาที่ Case เกิดเหตุการณ์
CaseControl
ทารกAB
ANCInadequateAdequate
สถานะวันที่ 5เกิด Outcomeยังไม่เกิด Outcome
Risk Set11

Matched Pair มีโครงสร้างอย่างไร

ตัวอย่างนี้ใช้การจับคู่แบบ 1:1

ดังนั้น 20 Matched Pairs เท่ากับ 40 Observation Rows ในฐานข้อมูล แต่ในการศึกษาจริงอาจไม่ใช่ทารก 40 คนที่ไม่ซ้ำกัน เพราะทารกคนหนึ่งอาจปรากฏในหลาย Risk Sets

ชุดข้อมูลตัวอย่าง: 20 Matched Pairs

เพื่อให้เห็นความแตกต่างของโมเดล ตัวอย่างนี้ใช้ข้อมูลสมมติ 20 Matched Pairs นับตาม ANC ของ Case และ ANC ของ Control

ตัวอย่างคำนวณด้วยมือ 20 Matched Pairs จำแนกตาม ANC ของ Case และ ANC ของ Control
ANC ของ CaseANC ของ Controlจำนวนคู่
InadequateInadequate8
AdequateAdequate7
InadequateAdequate4
AdequateInadequate1
Total20

Concordant Pairs และ Discordant Pairs

ตรวจสอบจำนวนคู่: 8 + 7 + 4 + 1 = 20 คู่

แต่ละคู่มี Case หนึ่งรายการและ Control หนึ่งรายการเสมอ เราจึงมี Cases 20 รายการ และ Controls 20 รายการ

สังเกตว่าคู่เหล่านี้แบ่งเป็นสองประเภท

Concordant Pairs (15 คู่) คือคู่ที่ ANC เหมือนกัน

Discordant Pairs (5 คู่) คือคู่ที่ ANC แตกต่างกัน

Ordinary Logistic Regression: ไม่สนใจการจับคู่

Ordinary Logistic Regression ไม่ใช้ข้อมูลว่า Case รายใดถูกจับคู่กับ Control รายใด

โปรแกรมมองข้อมูลเป็น Case 20 รายการ และ Control 20 รายการ แล้วนำมานับเป็นตาราง 2 × 2

ตัวอย่างคำนวณด้วยมือ 20 คู่ที่นับรวมเป็นตาราง 2 × 2 ตารางเดียว โดยไม่สนใจการจับคู่
ANCCaseControl
Inadequate129
Adequate811
Total2020

ทีละขั้น: Ordinary Odds Ratio

ตัวเลขแต่ละช่องมาจากตารางคู่เดิม

  • Case ที่มี Inadequate ANC = 8 + 4 = 12
  • Case ที่มี Adequate ANC = 7 + 1 = 8
  • Control ที่มี Inadequate ANC = 8 + 1 = 9
  • Control ที่มี Adequate ANC = 7 + 4 = 11
  1. ขั้นที่ 1. Exposure Odds ในกลุ่ม Cases

    \[ \text{Odds among cases} = \frac{12}{8} = 1.50 \]

    ใน Case ทั้งหมด 20 รายการ มีผู้ที่ ANC ไม่เพียงพอ 12 รายการ และเพียงพอ 8 รายการ นี่คือ Odds ของ Inadequate ANC ในกลุ่ม Cases

  2. ขั้นที่ 2. Exposure Odds ในกลุ่ม Controls

    \[ \text{Odds among controls} = \frac{9}{11} = 0.818 \]

    ใน Control ทั้งหมด 20 รายการ มีผู้ที่ ANC ไม่เพียงพอ 9 รายการ และเพียงพอ 11 รายการ นี่คือ Odds ของ Inadequate ANC ในกลุ่ม Controls

  3. ขั้นที่ 3. Ordinary Odds Ratio

    \[ \mathrm{OR} = \frac{12/8}{9/11} = \frac{1.50}{0.818} = 1.83 \]

    นำ Odds ของทั้งสองกลุ่มมาหารกัน

ผลลัพธ์: Ordinary Logistic Regression ให้ OR = 1.83 หมายความว่า Odds ของ Inadequate ANC ในกลุ่ม Cases สูงกว่ากลุ่ม Controls ประมาณ 1.83 เท่า เมื่อวิเคราะห์แบบรวมโดยไม่ใช้ข้อมูลการจับคู่

อย่างไรก็ตาม วิธีนี้ละเลย Risk Sets ที่ถูกกำหนดไว้ในการสุ่มตัวอย่าง จึงไม่ได้เปรียบเทียบผู้ที่อยู่ภายใน Risk Set เดียวกันตามที่ Study Design กำหนด

Conditional Logistic Regression: รักษา Matched Sets ไว้

Conditional Logistic Regression ถามคำถามที่ต่างออกไป

ทำไม Concordant Pairs จึงไม่ช่วยประมาณ ANC Effect

พิจารณาคู่ต่อไปนี้

Concordant Pair: ทั้ง Case และ Control มี Inadequate ANC
CaseControl
ANCInadequateInadequate

Discordant Pairs ให้ข้อมูลอย่างไร

พิจารณาเฉพาะ 5 คู่ที่ ANC แตกต่างกัน

ตัวอย่างคำนวณด้วยมือ 5 Discordant Pairs
ANC ของ CaseANC ของ Controlจำนวนคู่
InadequateAdequate4
AdequateInadequate1
Total5

ทำไม Conditional Logistic Regression จึงทำงานแบบนี้

สิ่งสำคัญไม่ใช่แค่จำสูตร 4/1 แต่ต้องเข้าใจว่าเหตุใด Conditional Likelihood จึงนำไปสู่สูตรนี้

สมมติว่าแต่ละ Matched Pair มี Case เพียงหนึ่งราย Conditional Logistic Regression พิจารณาความน่าจะเป็นที่สมาชิกคนหนึ่งจะเป็น Case โดยมีเงื่อนไขว่าในคู่นั้นเกิด Outcome หนึ่งครั้ง เมื่ออ่านความน่าจะเป็นของ Case ที่สังเกตได้ภายใต้เงื่อนไขนี้เป็นฟังก์ชันของ coefficient จะได้ Conditional Likelihood [2]

กำหนดให้ $X = 1$ หมายถึง Inadequate ANC และ $X = 0$ หมายถึง Adequate ANC ให้ $\beta$ คือ Regression Coefficient ของ ANC และ $\exp(\beta)$ คือ Conditional Odds Ratio

  1. คนที่มี Inadequate ANC เป็น Case

    \[ P = \frac{\exp(\beta)}{1 + \exp(\beta)} \]

    สำหรับคู่ที่ ANC แตกต่างกัน นี่คือความน่าจะเป็นตามโมเดลที่คนมี Inadequate ANC จะเป็น Case

  2. คนที่มี Adequate ANC เป็น Case

    \[ 1 - P = \frac{1}{1 + \exp(\beta)} \]

    ส่วนนี่คือความน่าจะเป็นที่คนมี Adequate ANC จะเป็น Case แทน

  3. Conditional Likelihood

    \[ L(\beta) \propto P^{4}\,(1 - P)^{1} \]

    ในข้อมูลของเรา พบเหตุการณ์รูปแบบแรก 4 คู่ และรูปแบบที่สอง 1 คู่ Conditional Likelihood ของส่วนที่ขึ้นกับ ANC จึงแปรผันตามผลคูณนี้

  4. ค่าสูงสุด

    \[ P = \frac{4}{5} = 0.80 \]

    นี่คือค่า $P$ ที่ทำให้ Likelihood สูงสุด

  5. กลับสู่ Odds Ratio

    \[ \exp(\beta) = \frac{P}{1 - P} = \frac{0.80}{0.20} = 4.00 \]

    นี่คือเหตุผลทางคณิตศาสตร์ที่ Conditional Logistic Regression ให้ OR = 4.00

  6. Concordant Pairs

    \[ P_{\text{concordant}} = \frac{1}{2} \]

    สำหรับ Concordant Pairs ไม่ว่า $\beta$ จะมีค่าเท่าไร ความน่าจะเป็นเชิงเงื่อนไขของรูปแบบที่สังเกตได้เท่ากับ 1/2 จึงไม่ช่วยระบุค่า $\beta$ ในโมเดลตัวแปรเดียวนี้

ผลลัพธ์: กล่าวอีกอย่างคือ Conditional Likelihood ใช้ความแตกต่างภายในคู่ ไม่ใช่เพียงความแตกต่างของจำนวน Exposure ระหว่าง Cases และ Controls ทั้งหมด ซึ่งในที่นี้ให้ OR = 4.00

เปรียบเทียบสองโมเดล

ตัวอย่างคำนวณด้วยมือ สองโมเดลเคียงกันบน 20 Matched Pairs ชุดเดียวกัน
FeatureOrdinary LogisticConditional Logistic
ข้อมูล20 Matched Pairs20 Matched Pairs
Observation Rows4040
ใช้ set_idไม่ใช้ใช้
การเปรียบเทียบPooled Cases vs ControlsWithin Matched Sets
วิธีประมาณUnconditional LikelihoodConditional Likelihood
OR ในตัวอย่าง1.834.00
รองรับ Design นี้โดยตรงไม่ใช่ในรูปแบบที่ละเลย Matchingใช่

ความแตกต่างนี้หมายถึงอะไร และไม่ได้หมายถึงอะไร

ความแตกต่างนี้ไม่ได้หมายความว่า Ordinary Logistic Regression เป็นโมเดลที่ผิดเสมอไป

แต่การใช้ Ordinary Logistic Regression โดยไม่คำนึงถึง Matched Risk Sets อาจทำให้ประมาณ Effect ที่ไม่ตรงกับ Study Design และอาจเกิด Bias ได้

นอกจากนี้ ไม่ใช่ทุกการศึกษาที่ Conditional OR จะมากกว่า Ordinary OR เสมอ ความแตกต่างขึ้นกับโครงสร้างข้อมูล การจับคู่ Confounding และคุณสมบัติของ Odds Ratio เอง เช่น Non-collapsibility คือ Odds Ratio ภายในกลุ่มย่อยอาจต่างจาก Odds Ratio ที่เฉลี่ยข้ามกลุ่มย่อยได้แม้ไม่มี Confounding [3] ตอนของชุดบทความนี้ว่าด้วย Conditional และ Marginal Odds Ratio อธิบายคุณสมบัตินี้อย่างละเอียด

ตัวอย่างคำนวณด้วยมือ เปลี่ยนจำนวนคู่ในแต่ละรูปแบบ คือได้รับ Exposure ทั้งสองคน เฉพาะ Case ได้รับ Exposure เฉพาะ Control ได้รับ Exposure และไม่ได้รับทั้งสองคน แผงจะสร้างตารางรวม Odds Ratio แบบไม่จับคู่ Odds Ratio แบบจับคู่ และจำนวนคู่ที่ให้ข้อมูล (Discordant Pairs) ขึ้นใหม่ แผงเริ่มที่ตัวอย่างคำนวณด้วยมือ: 8, 4, 1 และ 7 คู่ให้ 1.83 และ 4.00 จากคู่ที่ให้ข้อมูล 5 คู่ ลองเพิ่ม Concordant Pairs แล้วดูว่า Odds Ratio แบบจับคู่คงที่ ขณะที่แบบไม่จับคู่เปลี่ยน

ประเด็นขั้นสูง: clogit เกี่ยวข้องกับ Cox Regression อย่างไร

ในการศึกษาแบบ Concurrent หรือ Incidence-Density Sampling เราสุ่ม Controls จากผู้ที่ยังอยู่ใน Risk Set ณ เวลาที่ Case เกิด Outcome

Hazard คืออัตราการเกิดเหตุการณ์ชั่วขณะ ณ เวลา $t$ ในผู้ที่ยังไม่เกิดเหตุการณ์ ภายใต้ Cox Proportional Hazards Model

$$h(t \mid X) = h_0(t) \times \exp(\beta X)$$

โดย $h_0(t)$ คือ Baseline Hazard ณ เวลา $t$ และ $\exp(\beta X)$ คือ Relative Hazard ของคนที่มี Exposure $X$

ถ้ามี Event หนึ่งครั้ง ณ เวลา $t$ ส่วนของ Cox Partial Likelihood สำหรับ Case รายหนึ่งจะมีรูปแบบ

$$\text{Likelihood} = \frac{\text{Relative Hazard ของ Case}}{\text{ผลรวม Relative Hazards ของทุกคนใน Risk Set}}$$

คือ Relative Hazard ของ Case หารด้วยผลรวม Relative Hazards ของทุกคนใน Risk Set

Conditional Logistic Regression ใช้โครงสร้าง Likelihood ลักษณะเดียวกัน แต่เปรียบเทียบ Case กับ Controls ที่สุ่มมาใน Matched Risk Set ในคู่แบบ 1:1 Risk Set นั้นมีเพียง Case กับ Control ของมัน ความน่าจะเป็น $P$ ข้างบนจึงมีรูปแบบอย่างที่เห็น

ด้วยเหตุนี้ ภายใต้การสุ่มและสมมติฐานที่เหมาะสม ค่า $\exp(\beta)$ จาก Conditional Logistic Regression สามารถใช้ประมาณ Hazard Ratio คืออัตราส่วนของ Hazard สองค่า ที่เป็นเป้าหมายของ Cox Model ใน Full Cohort ได้

หาก Hazard Ratio คงที่ตลอดช่วงติดตาม และการสุ่ม Controls กับการวิเคราะห์สอดคล้องกับเวลาเกิด Event เราสามารถตีความค่าประมาณเป็น Relative Hazard หรือ Instantaneous Incidence Rate Ratio ได้ โดยไม่ต้องอาศัย Rare Disease Assumption คือสมมติฐานว่า Outcome พบน้อยพอที่ Odds Ratio จะใกล้เคียง Risk Ratio [4]

Stata: คู่ชุดเดียวกันในรูป Stratified Cox Model

โค้ด Stata c7_sim.do (บรรทัด 259-263 จาก 265)
* the same likelihood as a Cox model stratified by matched set: the case has its event at time 1 and its
* control is censored at time 2, so each risk set holds exactly the pair
generate byte t = 2 - case
stset t, failure(case)
stcox i.inadequate_anc, strata(set_id) nolog
ผลลัพธ์จากการรัน c7_sim.log
. * the same likelihood as a Cox model stratified by matched set: the case has its event at time 1 and its
. * control is censored at time 2, so each risk set holds exactly the pair
. generate byte t = 2 - case

. stset t, failure(case)

Survival-time data settings

         Failure event: case!=0 & case<.
Observed time interval: (0, t]
     Exit on or before: failure

--------------------------------------------------------------------------
         40  total observations
          0  exclusions
--------------------------------------------------------------------------
         40  observations remaining, representing
         20  failures in single-record/single-failure data
         60  total analysis time at risk and under observation
                                                At risk from t =         0
                                     Earliest observed entry t =         0
                                          Last observed exit t =         2

. stcox i.inadequate_anc, strata(set_id) nolog

        Failure _d: case
  Analysis time _t: t

Stratified Cox regression with no ties
Strata variable: set_id

No. of subjects = 40                                    Number of obs =     40
No. of failures = 20
Time at risk    = 60
                                                        LR chi2(1)    =   1.93
Log likelihood = -12.89922                              Prob > chi2   = 0.1650

----------------------------------------------------------------------------------
              _t | Haz. ratio   Std. err.      z    P>|z|     [95% conf. interval]
-----------------+----------------------------------------------------------------
1.inadequate_anc |          4   4.472136     1.24   0.215     .4470826    35.78757
----------------------------------------------------------------------------------
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองเบื้องหลังชุดบทความนี้และผลลัพธ์ของสคริปต์ Case แต่ละรายได้เวลาเกิดเหตุการณ์ที่เวลา 1 และ Control ของมันถูก censor ที่เวลา 2 ทุก Risk Set จึงมีเพียงหนึ่งคู่ Cox Model ที่ stratify ด้วย set_id จึงพิมพ์ Hazard Ratio เป็น 4 คือ 4.00 พร้อม Log Likelihood และช่วงเชื่อมั่นเท่ากับของ clogit เพราะในที่นี้ Partial Likelihood ของมันกับ Conditional Likelihood คือสิ่งเดียวกัน นี่คือ Cox Model บนคู่ที่สุ่มมาเท่านั้น Cox Model บน Full Cohort จะใช้ทุก Risk Set และไม่จำเป็นต้องได้ 4.00
ต้องแยก Effect Measures ทั้งสี่นี้ให้ชัดเจน
Effect Measureความหมาย
Odds Ratio (OR)อัตราส่วนของ Odds
Risk Ratio (RR)อัตราส่วนของ Cumulative Risks ในช่วงเวลาที่กำหนด
Incidence Rate Ratio (IRR)อัตราส่วนของ Event Rates ต่อ Person-Time
Hazard Ratio (HR)อัตราส่วนของ Instantaneous Hazards ณ เวลาที่กำหนด

สิ่งที่ Conditional Logistic Regression ไม่ได้ทำ

Conditional Logistic Regression ไม่ได้ทำให้ OR กลายเป็น RR โดยอัตโนมัติ

การตีความ OR จาก Risk-Set Sampling เป็น HR หรือ Rate Ratio ต้องอาศัยเงื่อนไขของ Design, Sampling และ Hazard Model โดยเฉพาะการจัดการ Matching ตาม Event Time และสมมติฐานเกี่ยวกับการเปลี่ยนแปลงของ Effect ตามเวลา [5]

หาก Hazard Ratio เปลี่ยนไปตามเวลา ค่าจากโมเดลอาจสะท้อนการเฉลี่ย Effect ตามน้ำหนักของเหตุการณ์ มากกว่าจะเป็น HR คงที่ค่าเดียวที่อธิบายทุกช่วงเวลาได้

ทำซ้ำตัวอย่างใน Stata

เราสามารถสร้างตัวอย่างนี้ได้โดยไม่ต้องใช้ Dataset ภายนอก ต่อไปนี้คือคำสั่งของตัวอย่างที่คำนวณด้วยมือ

clear

* Four patterns of matched pairs
input byte anc_case anc_ctrl n_pairs
1 1 8
0 0 7
1 0 4
0 1 1
end

* Create 20 matched sets
expand n_pairs
gen long set_id = _n

* Reshape to one row per observation
reshape long anc_, i(set_id) j(role) string

rename anc_ inadequate_anc

* Case indicator
gen byte case = (role == "case")

* Check the matched-set structure
bysort set_id: assert _N == 2
bysort set_id: assert case[1] != case[2]

* Pooled 2x2 table
tab inadequate_anc case

* Ordinary logistic regression
logistic case i.inadequate_anc

* Conditional logistic regression
clogit case i.inadequate_anc, ///
    group(set_id) or

Stata อธิบายคำสั่ง clogit ไว้ในคู่มืออ้างอิง [6] และ Stata FAQ อธิบายว่าทำไม clogit จึงตัด Covariate ที่ไม่แปรผันภายใน Matched Set ออกจากโมเดล [7]

Expected Point Estimates ทั้งสองโมเดลควรแสดง Point Estimate ตามตัวอย่างที่คำนวณด้วยมือ
ModelExpected OR
logistic1.83
clogit4.00

set_id ในการศึกษาจริง และผลการรัน

ในการศึกษาจริงให้ใช้ set_id ที่สร้างจากขั้นตอนการสุ่ม Risk-Set Controls ไม่ใช่สร้าง Set ID ใหม่โดยสุ่มจับคู่หลังจากได้ข้อมูลมาแล้ว

แผงด้านล่างรันขั้นตอนเดียวกันด้วยสคริปต์จำลองเบื้องหลังชุดบทความนี้ ใน Stata แล้วตามด้วย R พร้อมผลลัพธ์ที่แต่ละโปรแกรมพิมพ์ออกมา Ordinary Logistic Regression ได้ 1.83 และ Conditional Logistic Regression ได้ 4.00 ตรงกับที่คำนวณด้วยมือ

Stata: ป้อนข้อมูล 20 คู่

โค้ด Stata c7_sim.do (บรรทัด 197-225 จาก 265)
clear
input byte anc_case byte anc_ctrl int n_pairs
1 1 8
0 0 7
1 0 4
0 1 1
end
quietly summarize n_pairs
canon pairs.n 0 r(sum)
quietly summarize n_pairs if anc_case == anc_ctrl
canon pairs.concordant 0 r(sum)
quietly summarize n_pairs if anc_case != anc_ctrl
canon pairs.discordant 0 r(sum)
quietly summarize n_pairs if anc_case == 1 & anc_ctrl == 0
canon pairs.case_only_inadequate 0 r(sum)
quietly summarize n_pairs if anc_case == 0 & anc_ctrl == 1
canon pairs.control_only_inadequate 0 r(sum)
expand n_pairs
drop n_pairs
generate int set_id = _n
reshape long anc_, i(set_id) j(role) string
rename anc_ inadequate_anc
generate byte case = role == "case"
bysort set_id: assert _N == 2
bysort set_id (case): assert case[1] == 0 & case[2] == 1
quietly count
canon pairs.rows 0 r(N)
* the pooled 2 x 2 table that ordinary logistic regression sees
tabulate inadequate_anc case
ผลลัพธ์จากการรัน c7_sim.log
. clear

. input byte anc_case byte anc_ctrl int n_pairs

     anc_case  anc_ctrl   n_pairs
  1. 1 1 8
  2. 0 0 7
  3. 1 0 4
  4. 0 1 1
  5. end

. quietly summarize n_pairs

. canon pairs.n 0 r(sum)
CANON c7.pairs.n 20

. quietly summarize n_pairs if anc_case == anc_ctrl

. canon pairs.concordant 0 r(sum)
CANON c7.pairs.concordant 15

. quietly summarize n_pairs if anc_case != anc_ctrl

. canon pairs.discordant 0 r(sum)
CANON c7.pairs.discordant 5

. quietly summarize n_pairs if anc_case == 1 & anc_ctrl == 0

. canon pairs.case_only_inadequate 0 r(sum)
CANON c7.pairs.case_only_inadequate 4

. quietly summarize n_pairs if anc_case == 0 & anc_ctrl == 1

. canon pairs.control_only_inadequate 0 r(sum)
CANON c7.pairs.control_only_inadequate 1

. expand n_pairs
(16 observations created)

. drop n_pairs

. generate int set_id = _n

. reshape long anc_, i(set_id) j(role) string
(j = case ctrl)

Data                               Wide   ->   Long
-----------------------------------------------------------------------------
Number of observations               20   ->   40
Number of variables                   3   ->   3
j variable (2 values)                     ->   role
xij variables:
                      anc_case anc_ctrl   ->   anc_
-----------------------------------------------------------------------------

. rename anc_ inadequate_anc

. generate byte case = role == "case"

. bysort set_id: assert _N == 2

. bysort set_id (case): assert case[1] == 0 & case[2] == 1

. quietly count

. canon pairs.rows 0 r(N)
CANON c7.pairs.rows 40

. * the pooled 2 x 2 table that ordinary logistic regression sees
. tabulate inadequate_anc case

inadequate |         case
      _anc |         0          1 |     Total
-----------+----------------------+----------
         0 |        11          8 |        19
         1 |         9         12 |        21
-----------+----------------------+----------
     Total |        20         20 |        40
ข้อมูลตัวอย่างคำนวณด้วยมือ ป้อนในสคริปต์จำลองของชุดบทความนี้ เป็นข้อความที่ตัดมาจากสคริปต์นั้นและผลลัพธ์ของสคริปต์ บล็อก input พิมพ์รูปแบบของคู่สี่แบบพร้อมจำนวนคู่ ขั้น expand และ reshape ทำให้มีหนึ่งแถวต่อสมาชิกของคู่ โดยมี set_id ของแต่ละคู่ และ assert ตรวจว่าแต่ละคู่มี Case หนึ่งรายและ Control หนึ่งราย คำสั่ง tabulate คือตารางรวมที่ Ordinary Logistic Regression มองเห็น บรรทัดที่ขึ้นต้นด้วย CANON พิมพ์โดยฟังก์ชันช่วยเล็ก ๆ ในสคริปต์ที่สะท้อนผลลัพธ์แต่ละค่าออกมา ให้อ่านตัวเลขท้ายบรรทัดและไม่ต้องสนใจคำนำหน้า

Stata: Ordinary Logistic Regression กับคู่ที่จับคู่

โค้ด Stata c7_sim.do (บรรทัด 240-241 จาก 265)
* ordinary logistic regression ignores the matched sets
logistic case i.inadequate_anc, nolog
ผลลัพธ์จากการรัน c7_sim.log
. * ordinary logistic regression ignores the matched sets
. logistic case i.inadequate_anc, nolog

Logistic regression                                     Number of obs =     40
                                                        LR chi2(1)    =   0.91
                                                        Prob > chi2   = 0.3413
Log likelihood = -27.27303                              Pseudo R2     = 0.0163

----------------------------------------------------------------------------------
            case | Odds ratio   Std. err.      z    P>|z|     [95% conf. interval]
-----------------+----------------------------------------------------------------
1.inadequate_anc |   1.833333   1.174412     0.95   0.344      .522362    6.434448
           _cons |   .7272727   .3379347    -0.69   0.493      .292535    1.808076
----------------------------------------------------------------------------------
Note: _cons estimates baseline odds.
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองของชุดบทความนี้และผลลัพธ์ของสคริปต์ เมื่อไม่สนใจ Matched Sets Odds Ratio เท่ากับ 1.83 ช่วงเชื่อมั่น 95% คือ 0.52 ถึง 6.43 ในข้อมูล Case-Control ค่า _cons ขึ้นกับจำนวน Control ที่สุ่มต่อ Case หนึ่งราย ไม่ใช่ Baseline Odds ของภาวะแทรกซ้อน

Stata: การประมาณแบบรวมด้วย Cluster-Robust Standard Error

โค้ด Stata c7_sim.do (บรรทัด 246-247 จาก 265)
* clustering the standard error on the matched set changes the interval, not the odds ratio
logistic case i.inadequate_anc, vce(cluster set_id) nolog
ผลลัพธ์จากการรัน c7_sim.log
. * clustering the standard error on the matched set changes the interval, not the odds ratio
. logistic case i.inadequate_anc, vce(cluster set_id) nolog

Logistic regression                                     Number of obs =     40
                                                        Wald chi2(1)  =   1.82
                                                        Prob > chi2   = 0.1770
Log pseudolikelihood = -27.27303                        Pseudo R2     = 0.0163

                                    (Std. err. adjusted for 20 clusters in set_id)
----------------------------------------------------------------------------------
                 |               Robust
            case | Odds ratio   std. err.      z    P>|z|     [95% conf. interval]
-----------------+----------------------------------------------------------------
1.inadequate_anc |   1.833333    .823118     1.35   0.177     .7604568    4.419858
           _cons |   .7272727   .1778604    -1.30   0.193     .4503282    1.174534
----------------------------------------------------------------------------------
Note: _cons estimates baseline odds.
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองเบื้องหลังชุดบทความนี้และผลลัพธ์ของสคริปต์ นี่คือ Ordinary Logistic Regression แบบเดียวกัน แต่ใช้ vce(cluster set_id) เพื่อขอ Cluster-Robust Standard Error ซึ่งยอมให้สมาชิกสองคนในคู่เดียวกันสัมพันธ์กันได้ Odds Ratio ยังคงเป็น 1.83 มีเพียง Standard Error และช่วงเชื่อมั่น 95% ที่เปลี่ยน ในที่นี้เป็น 0.76 ถึง 4.42 หัวข้อความเข้าใจผิดที่พบบ่อยใกล้ท้ายบทความอธิบายว่าทำไมสิ่งนี้ไม่ได้ทำให้การประมาณแบบรวมกลายเป็นการวิเคราะห์แบบจับคู่

Stata: Conditional Logistic Regression กับคู่ที่จับคู่

โค้ด Stata c7_sim.do (บรรทัด 252-253 จาก 265)
* conditional logistic regression compares the case with its own control inside each matched set
clogit case i.inadequate_anc, group(set_id) or nolog
ผลลัพธ์จากการรัน c7_sim.log
. * conditional logistic regression compares the case with its own control inside each matched set
. clogit case i.inadequate_anc, group(set_id) or nolog

Conditional (fixed-effects) logistic regression         Number of obs =     40
                                                        LR chi2(1)    =   1.93
                                                        Prob > chi2   = 0.1650
Log likelihood = -12.89922                              Pseudo R2     = 0.0695

----------------------------------------------------------------------------------
            case | Odds ratio   Std. err.      z    P>|z|     [95% conf. interval]
-----------------+----------------------------------------------------------------
1.inadequate_anc |          4   4.472136     1.24   0.215     .4470826    35.78757
----------------------------------------------------------------------------------
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองเบื้องหลังชุดบทความนี้และผลลัพธ์ของสคริปต์ group(set_id) บอก clogit ว่าแถวใดเป็น Matched Set แต่ละชุด ซึ่งคือ Set ที่กำหนดไว้ตั้งแต่ขั้นตอนการสุ่ม และ or สั่งให้พิมพ์ Odds Ratio Stata แสดงเป็น 4 คือ 4.00 ช่วงเชื่อมั่น 95% คือ 0.45 ถึง 35.79

R: ข้อมูลคู่และ Ordinary Logistic Regression

โค้ด R c7_sim_r.R (บรรทัด 165-198 จาก 222)
pairs <- data.frame(anc_case = c(1, 0, 1, 0), anc_ctrl = c(1, 0, 0, 1), n_pairs = c(8, 7, 4, 1))
canon("pairs.n", sum(pairs$n_pairs), 0)
canon("pairs.concordant", sum(pairs$n_pairs[pairs$anc_case == pairs$anc_ctrl]), 0)
canon("pairs.discordant", sum(pairs$n_pairs[pairs$anc_case != pairs$anc_ctrl]), 0)
canon("pairs.case_only_inadequate", sum(pairs$n_pairs[pairs$anc_case == 1 & pairs$anc_ctrl == 0]), 0)
canon("pairs.control_only_inadequate", sum(pairs$n_pairs[pairs$anc_case == 0 & pairs$anc_ctrl == 1]), 0)
pp <- pairs[rep(seq_len(nrow(pairs)), pairs$n_pairs), ]
pp$set_id <- seq_len(nrow(pp))
m <- rbind(data.frame(set_id = pp$set_id, case = 1L, inadequate_anc = pp$anc_case),
           data.frame(set_id = pp$set_id, case = 0L, inadequate_anc = pp$anc_ctrl))
m <- m[order(m$set_id, m$case), ]
stopifnot(all(table(m$set_id) == 2), all(tapply(m$case, m$set_id, sum) == 1))
canon("pairs.rows", nrow(m), 0)
# the pooled 2 x 2 table that ordinary logistic regression sees
print(table(inadequate_anc = m$inadequate_anc, case = m$case))
a <- sum(m$case == 1 & m$inadequate_anc == 1)
bb <- sum(m$case == 1 & m$inadequate_anc == 0)
cc <- sum(m$case == 0 & m$inadequate_anc == 1)
dd <- sum(m$case == 0 & m$inadequate_anc == 0)
canon("pooled.cases_inadequate", a, 0)
canon("pooled.cases_adequate", bb, 0)
canon("pooled.controls_inadequate", cc, 0)
canon("pooled.controls_adequate", dd, 0)
canon("pooled.odds_cases", a / bb)
canon("pooled.odds_controls", cc / dd)
# ordinary logistic regression ignores the matched sets
fp <- glm(case ~ inadequate_anc, family = binomial, data = m)
print(summary(fp)$coefficients)
bp <- coef(fp)[["inadequate_anc"]]
sp <- sqrt(vcov(fp)["inadequate_anc", "inadequate_anc"])
canon("pooled.or", exp(bp))
canon("pooled.se", sp)
canon("pooled.or_lb", exp(bp - z * sp))
canon("pooled.or_ub", exp(bp + z * sp))
ผลลัพธ์จากการรัน c7_sim_r.log
> pairs <- data.frame(anc_case = c(1, 0, 1, 0), anc_ctrl = c(1,
+     0, 0, 1), n_pairs = c(8, 7, 4, 1))

> canon("pairs.n", sum(pairs$n_pairs), 0)
CANON c7.pairs.n 20

> canon("pairs.concordant", sum(pairs$n_pairs[pairs$anc_case ==
+     pairs$anc_ctrl]), 0)
CANON c7.pairs.concordant 15

> canon("pairs.discordant", sum(pairs$n_pairs[pairs$anc_case !=
+     pairs$anc_ctrl]), 0)
CANON c7.pairs.discordant 5

> canon("pairs.case_only_inadequate", sum(pairs$n_pairs[pairs$anc_case ==
+     1 & pairs$anc_ctrl == 0]), 0)
CANON c7.pairs.case_only_inadequate 4

> canon("pairs.control_only_inadequate", sum(pairs$n_pairs[pairs$anc_case ==
+     0 & pairs$anc_ctrl == 1]), 0)
CANON c7.pairs.control_only_inadequate 1

> pp <- pairs[rep(seq_len(nrow(pairs)), pairs$n_pairs),
+     ]

> pp$set_id <- seq_len(nrow(pp))

> m <- rbind(data.frame(set_id = pp$set_id, case = 1,
+     inadequate_anc = pp$anc_case), data.frame(set_id = pp$set_id,
+     case = 0, inadequate_anc = pp$anc_ctrl))

> m <- m[order(m$set_id, m$case), ]

> stopifnot(all(table(m$set_id) == 2), all(tapply(m$case,
+     m$set_id, sum) == 1))

> canon("pairs.rows", nrow(m), 0)
CANON c7.pairs.rows 40

> print(table(inadequate_anc = m$inadequate_anc, case = m$case))
              case
inadequate_anc  0  1
             0 11  8
             1  9 12

> a <- sum(m$case == 1 & m$inadequate_anc == 1)

> bb <- sum(m$case == 1 & m$inadequate_anc == 0)

> cc <- sum(m$case == 0 & m$inadequate_anc == 1)

> dd <- sum(m$case == 0 & m$inadequate_anc == 0)

> canon("pooled.cases_inadequate", a, 0)
CANON c7.pooled.cases_inadequate 12

> canon("pooled.cases_adequate", bb, 0)
CANON c7.pooled.cases_adequate 8

> canon("pooled.controls_inadequate", cc, 0)
CANON c7.pooled.controls_inadequate 9

> canon("pooled.controls_adequate", dd, 0)
CANON c7.pooled.controls_adequate 11

> canon("pooled.odds_cases", a/bb)
CANON c7.pooled.odds_cases 1.5000

> canon("pooled.odds_controls", cc/dd)
CANON c7.pooled.odds_controls 0.8182

> fp <- glm(case ~ inadequate_anc, family = binomial,
+     data = m)

> print(summary(fp)$coefficients)
                 Estimate Std. Error    z value  Pr(>|z|)
(Intercept)    -0.3184537  0.4646602 -0.6853476 0.4931246
inadequate_anc  0.6061358  0.6405884  0.9462172 0.3440378

> bp <- coef(fp)[["inadequate_anc"]]

> sp <- sqrt(vcov(fp)["inadequate_anc", "inadequate_anc"])

> canon("pooled.or", exp(bp))
CANON c7.pooled.or 1.8333

> canon("pooled.se", sp)
CANON c7.pooled.se 0.6406

> canon("pooled.or_lb", exp(bp - z * sp))
CANON c7.pooled.or_lb 0.5224

> canon("pooled.or_ub", exp(bp + z * sp))
CANON c7.pooled.or_ub 6.4344
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองฉบับ R เบื้องหลังชุดบทความนี้และผลลัพธ์ของสคริปต์ data frame m เก็บหนึ่งแถวต่อสมาชิกของคู่ glm() พิมพ์ coefficient ของ inadequate_anc บนมาตรวัด log odds และบรรทัด CANON ให้ Odds Ratio ของมัน 1.83 พร้อมขอบเขต บรรทัดที่ขึ้นต้นด้วย CANON พิมพ์โดยฟังก์ชันช่วยเล็ก ๆ ในสคริปต์ที่สะท้อนผลลัพธ์แต่ละค่าออกมา ให้อ่านตัวเลขท้ายบรรทัดและไม่ต้องสนใจคำนำหน้า

R: clogit() กับคู่ที่จับคู่

โค้ด R c7_sim_r.R (บรรทัด 206-208 จาก 222)
# conditional logistic regression compares the case with its own control inside each matched set
fc <- clogit(case ~ inadequate_anc + strata(set_id), data = m)
print(summary(fc))
ผลลัพธ์จากการรัน c7_sim_r.log
> fc <- clogit(case ~ inadequate_anc + strata(set_id),
+     data = m)

> print(summary(fc))
Call:
coxph(formula = Surv(rep(1, 40L), case) ~ inadequate_anc + strata(set_id),
    data = m, method = "exact")

  n= 40, number of events= 20

                coef exp(coef) se(coef)    z Pr(>|z|)
inadequate_anc 1.386     4.000    1.118 1.24    0.215

               exp(coef) exp(-coef) lower .95 upper .95
inadequate_anc         4       0.25    0.4471     35.79

Concordance= 0.575  (se = 0.075 )
Likelihood ratio test= 1.93  on 1 df,   p=0.2
Wald test            = 1.54  on 1 df,   p=0.2
Score (logrank) test = 1.8  on 1 df,   p=0.2
ข้อมูลตัวอย่างคำนวณด้วยมือ ข้อความที่ตัดมาจากสคริปต์จำลองฉบับ R เบื้องหลังชุดบทความนี้และผลลัพธ์ของสคริปต์ strata(set_id) ระบุ Matched Sets การเรียกที่พิมพ์ออกมาเป็น Cox Model เพราะ clogit() ประมาณ Conditional Likelihood ด้วยรูทีน Cox ของ R ซึ่งคือโครงสร้างร่วมที่อธิบายไว้ข้างบน คอลัมน์ exp(coef) คือ Matched Odds Ratio 4.00 และสองคอลัมน์สุดท้ายของตารางที่สองให้ช่วงเชื่อมั่น 95% ของมัน

ความเข้าใจผิดที่พบบ่อย

  • "clogit จับคู่ Cases กับ Controls ให้อัตโนมัติ"

    ไม่จริง clogit ใช้ Matched Sets ที่ผู้วิจัยกำหนดไว้ก่อนแล้วผ่าน group(set_id) ไม่ได้ทำ Matching ให้เอง

    วิธีแก้: สร้างรหัส Set ตั้งแต่ขั้นตอนการสุ่ม Risk-Set Controls แล้วส่งให้ clogit ผ่าน group(set_id)

  • "clogit ใช้เพียง Discordant Pairs ห้าคู่ แล้วทิ้งข้อมูลที่เหลือ"

    ไม่ถูกต้องในความหมายทั่วไป โมเดลใช้ Conditional Likelihood ของ Matched Sets ทั้งหมด แต่ในตัวอย่างนี้ที่มี Binary ANC เพียงตัวเดียว Concordant Pairs 15 คู่เพียงไม่ให้ข้อมูลเกี่ยวกับ ANC coefficient

    วิธีแก้: เก็บ Matched Sets ทุกชุดไว้ในข้อมูล และรายงานว่ามีกี่ Set ที่ Discordant ใน Exposure เพราะ Set เหล่านั้นเป็นผู้ให้ข้อมูลเกี่ยวกับ Exposure

  • "OR ที่ใหญ่กว่าแปลว่าโมเดลแม่นยำกว่า"

    ไม่จริง OR = 4.00 ไม่ได้พิสูจน์ว่าโมเดลมีความแม่นยำกว่า OR = 1.83 ในที่นี้ค่าประมาณที่ใหญ่กว่ายังมีช่วงเชื่อมั่นกว้างกว่ามาก คือ 0.45 ถึง 35.79 เทียบกับ 0.52 ถึง 6.43

    วิธีแก้: เลือกโมเดลจาก Study Design, Estimand, Model Assumptions และความเสี่ยงของ Bias ไม่ใช่จากขนาดของ OR

  • "Risk-Set Sampling ทำให้ OR เท่ากับ Risk Ratio เสมอ"

    ไม่จริง วิธีสุ่มแบบนี้ทำให้ Matched OR ประมาณ Relative Hazard หรือ Rate Ratio ได้ภายใต้เงื่อนไขที่เหมาะสม แต่ไม่ได้เท่ากับ 28-day Cumulative Risk Ratio โดยอัตโนมัติ

    วิธีแก้: ระบุ Effect Measure ที่ Design และสมมติฐานรองรับ และอย่ารายงาน Matched OR ว่าเป็น Risk Ratio

  • "ใช้ Robust Standard Errors แล้วแก้ปัญหาการละเลย Matching ได้"

    ไม่จริง Robust หรือ Cluster-Robust Standard Errors เปลี่ยนวิธีประเมินความไม่แน่นอนของ Coefficient แต่ไม่ได้เปลี่ยน Point Estimate ของ Ordinary Logistic Regression ให้กลายเป็น Conditional Estimate เมื่อ cluster ตามคู่ Pooled OR ยังคงเป็น 1.83 มีเพียงช่วงเชื่อมั่น 95% ที่ขยับจาก 0.52 ถึง 6.43 เป็น 0.76 ถึง 4.42

    วิธีแก้: วิเคราะห์ข้อมูลที่จับคู่ด้วย Risk-Set Sampling ด้วย Conditional Logistic Regression Standard Error ที่ต่างไปเปลี่ยนเฉพาะช่วงเชื่อมั่น ไม่เปลี่ยนค่าประมาณหรือคำถามที่ค่าประมาณนั้นตอบ

บทสรุป

Ordinary Logistic Regression และ Conditional Logistic Regression อาจให้ Odds Ratios แตกต่างกันมาก แม้ใช้ข้อมูลเดียวกัน เนื่องจาก Likelihood และโครงสร้างการเปรียบเทียบแตกต่างกัน

ในตัวอย่างนี้

สำหรับการศึกษา Nested Case-Control ที่ใช้ Incidence-Density Sampling การวิเคราะห์ด้วย Conditional Logistic Regression เป็นแนวทางมาตรฐานสำหรับรักษาโครงสร้างการสุ่มแบบ Matched Risk Sets

หากต้องการตีความค่าประมาณเป็น Hazard Ratio ต้องพิจารณาสมมติฐานของ Hazard Model และกระบวนการสุ่มตัวอย่างด้วย

อภิธานศัพท์

risk-set sampling (การสุ่มกลุ่มควบคุมจากกลุ่มเสี่ยง)
การสุ่ม Control ของ Case แต่ละรายจากผู้ที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลาที่ Case เกิดเหตุการณ์
risk set
ผู้ที่ยังมีโอกาสเกิด Outcome ณ เวลาที่ Case รายหนึ่งเกิดเหตุการณ์
nested case-control study (การศึกษาแบบ nested case-control)
การศึกษา Case-Control ที่ดึงมาจาก Cohort ที่กำหนดไว้ โดยสุ่ม Control จากผู้ที่อยู่ในกลุ่มเสี่ยง
incidence-density sampling (การเลือกกลุ่มควบคุมตามความหนาแน่นของอุบัติการณ์)
อีกชื่อหนึ่งของ Risk-Set Sampling คือสุ่ม Control จากผู้ที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลาที่ Case แต่ละรายเกิดเหตุการณ์
matched set (ชุดที่จับคู่)
Case หนึ่งรายพร้อม Control ที่สุ่มมาให้ ใช้รหัส Set เดียวกัน ในการจับคู่ 1:1 คือหนึ่งคู่
concordant pair (คู่ที่สอดคล้องกัน)
Matched Pair ที่ Case และ Control มี Exposure เหมือนกัน เมื่อมี Binary Exposure ตัวเดียว คู่นี้ไม่ให้ข้อมูลเกี่ยวกับ Exposure ใน Conditional Logistic Regression
discordant pair (คู่ที่ไม่สอดคล้องกัน)
Matched Pair ที่ Case และ Control มี Exposure ต่างกัน เมื่อจับคู่ 1:1 มี Binary Exposure ตัวเดียวและไม่มี Covariates อื่น Matched OR คืออัตราส่วนของคู่สองชนิดนี้
conditional likelihood
ความน่าจะเป็นว่าสมาชิกคนใดของ Matched Set เป็น Case เมื่อกำหนดว่า Set นั้นมี Case เพียงหนึ่งราย อ่านเป็นฟังก์ชันของ coefficient
conditional logistic regression
Logistic Model ที่ประมาณผ่าน Conditional Likelihood ทำให้ Case แต่ละรายถูกเปรียบเทียบกับสมาชิกใน Matched Set ของตัวเองเท่านั้น
non-collapsibility (ความไม่ยุบรวมได้)
คุณสมบัติของ Odds Ratio และ Hazard Ratio ที่ค่าที่เฉลี่ยข้ามกลุ่มย่อยอาจต่างจากค่าร่วมภายในกลุ่มย่อยได้ แม้ไม่มี Confounding
hazard (ฮาซาร์ด)
อัตราการเกิดเหตุการณ์ชั่วขณะ ณ เวลา t ในผู้ที่ยังอยู่ในกลุ่มเสี่ยง
partial likelihood
Likelihood ของ Cox Model: สำหรับแต่ละ Event คือ Relative Hazard ของผู้ที่เกิด Event หารด้วยผลรวม Relative Hazards ของทุกคนใน Risk Set
hazard ratio (อัตราส่วนฮาซาร์ด)
อัตราส่วนของอัตราการเกิดเหตุการณ์ชั่วขณะระหว่างกลุ่ม ซึ่งไม่ใช่อัตราส่วนของความเสี่ยง
rare disease assumption
สมมติฐานว่า Outcome พบน้อยพอที่ Odds Ratio จะใกล้เคียง Risk Ratio Risk-Set Sampling ไม่ต้องใช้สมมติฐานนี้เมื่อตีความเป็น Hazard Ratio
cluster-robust standard error
Standard Error ที่ยอมให้ข้อมูลภายใน Cluster เดียวกัน เช่น Matched Pair สัมพันธ์กันได้ เปลี่ยนช่วงเชื่อมั่นแต่ไม่เปลี่ยนค่าประมาณ

เอกสารอ้างอิง

  1. Langholz B, Goldstein L. Risk set sampling in epidemiologic cohort studies. Stat Sci. 1996;11(1):35-53. doi:10.1214/ss/1032209663 https://doi.org/10.1214/ss/1032209663
  2. Breslow NE, Day NE. Statistical Methods in Cancer Research, Volume I: The Analysis of Case-Control Studies. IARC Scientific Publications No. 32. Lyon: International Agency for Research on Cancer; 1980. https://publications.iarc.who.int/Book-And-Report-Series/Iarc-Scientific-Publications/Statistical-Methods-In-Cancer-Research-Volume-I-The-Analysis-Of-Case-Control-Studies-1980
  3. Greenland S, Pearl J, Robins JM. Confounding and collapsibility in causal inference. Stat Sci. 1999;14(1):29-46. doi:10.1214/ss/1009211805 https://doi.org/10.1214/ss/1009211805
  4. Greenland S, Thomas DC. On the need for the rare disease assumption in case-control studies. Am J Epidemiol. 1982;116(3):547-553. doi:10.1093/oxfordjournals.aje.a113439 https://doi.org/10.1093/oxfordjournals.aje.a113439
  5. Kerr S, Greenland S, Jeffrey K, et al. Understanding and reporting odds ratios as rate-ratio estimates in case-control studies. J Glob Health. 2023;13:04101. doi:10.7189/jogh.13.04101 https://doi.org/10.7189/jogh.13.04101
  6. StataCorp. Stata Base Reference Manual: [R] clogit. Stata documentation (PDF) at stata.com. Accessed 11 October 2026. https://www.stata.com/manuals/rclogit.pdf
  7. Gould W. Within group collinearity in conditional logistic regression. Stata FAQ, StataCorp. Accessed 17 October 2026. https://www.stata.com/support/faqs/statistics/within-group-collinearity-and-clogit/

ประเด็นสำคัญ

  • Estimator ตีความแยกจาก Study Design ไม่ได้: 20 Matched Pairs ชุดเดียวกันให้ 1.83 จาก Ordinary Logistic Regression และ 4.00 จาก Conditional Logistic Regression เพราะสองโมเดลตอบคำถามต่างกัน
  • ใน Risk-Set Sampling Control แต่ละรายมาจากทารกที่ยังอยู่ในกลุ่มเสี่ยง ณ เวลาที่ Case ของมันเกิด Outcome Control อาจกลายเป็น Case ภายหลังได้ และ Matched Set คือหน่วยของการเปรียบเทียบ
  • การรวมให้ (12/8)/(9/11) = 1.50/0.818 = 1.83 ส่วนการวิเคราะห์ภายใน Matched Set เหลือ Discordant Pairs ที่ให้ 4/1 = 4.00 ซึ่ง Conditional Likelihood P ยกกำลัง 4 คูณ (1 - P) มีค่าสูงสุดที่ P = 0.80
  • ภายใต้การสุ่มและสมมติฐานที่เหมาะสม Matched OR ประมาณ Hazard Ratio ของ Cox ไม่ใช่ Risk Ratio และไม่จำเป็นต้องเท่ากับค่าประมาณจาก Cox บน Full Cohort เป๊ะ
  • เมื่อมี Discordant Pairs เพียง 5 คู่ ต้องรายงาน 4.00 พร้อม 95% Confidence Interval คือ 0.45 ถึง 35.79 และ Robust Standard Error ไม่ได้ทำให้ค่าประมาณแบบรวมกลายเป็นค่าแบบจับคู่

อ่านต่อในวิกิ: [[conditional-vs-marginal-or-th]] [[case-control-sampling-schemes-stata-and-r-th]] [[conditional-logistic-regression]]

0
ถึงนักอ่านชาวไทยและต่างชาติทำความเข้าใจบริบททางการแพทย์ของผมอ่านต่อ →ถึงนักอ่านชาวไทยและต่างชาติทำความเข้าใจเนื้อหาของผมที่นอกเหนือจากการแพทย์อ่านต่อ →

ความคิดเห็น

ยังไม่มีความคิดเห็น มาเป็นคนแรกกันเลย

เข้าสู่ระบบเพื่อแสดงความคิดเห็น