HARKing: การสำรวจข้อมูลเป็นเรื่องซื่อสัตย์ จนกว่าจะเขียนใหม่ว่าสมมติฐานเกิดขึ้นเมื่อใด

On this page
Read the English version
บทคัดย่อ
ผลในกลุ่มย่อยที่พบขณะสำรวจข้อมูลเป็นเพียงสมมติฐาน ไม่ใช่การยืนยัน HARKing (hypothesizing after the results are known) หรือการตั้งสมมติฐานหลังรู้ผล คือการนำเสนอสมมติฐานเช่นนั้นราวกับว่าได้ระบุไว้ก่อนเห็นข้อมูล การเขียนใหม่นี้ซ่อนว่าได้ตรวจการวิเคราะห์ไปกี่แบบ ผู้อ่านจึงประเมินบทบาทของความบังเอิญไม่ได้ เมื่อมองข้อมูล 20 ครั้งอย่างอิสระต่อกันที่ระดับ 5% และไม่มีผลจริงเลย โอกาสที่จะได้ค่า P ต่ำกว่า 0.05 อย่างน้อยหนึ่งค่าคือ 0.64 ในทะเบียน (registry) ผู้ป่วยกระดูกสะโพกหักที่เป็นข้อมูลจำลอง รายการแบ่งกลุ่มย่อยยี่สิบแบบที่ประกาศไว้ของผลการผ่าตัดเร็วต่อภาวะสับสนเฉียบพลัน (delirium) ถูกวิเคราะห์ด้วยการถ่วงน้ำหนักด้วยส่วนกลับของความน่าจะเป็น (inverse probability weighting) และมีห้าแบบที่ได้ค่า P ต่ำกว่า 0.05 ในแบบจำลองที่ใช้สร้างข้อมูล มีเพียงความเปราะบาง (frailty) ที่เปลี่ยนอัตราส่วนออดส์ (odds ratio) ส่วนอีกสี่แบบแฝงความเปราะบางและความเสี่ยงพื้นฐานที่ต่างกัน ซึ่งทำให้อัตราส่วนความเสี่ยงเปลี่ยนไป บทความนี้สรุปว่า การสำรวจข้อมูลชอบธรรมเมื่อระบุไว้ชัดว่าเป็นการสำรวจ ควรรายงานทุกกลุ่มย่อยที่ตรวจ และผลที่พบหลังเห็นข้อมูลต้องมีข้อมูลชุดใหม่ก่อนจะเรียกว่ายืนยันแล้ว
กลุ่มย่อยที่น่าทึ่งในทะเบียนกระดูกสะโพกหัก
ทะเบียน (registry) กระดูกสะโพกหักระดับประเทศเก็บข้อมูลผู้สูงอายุ 20,000 คน สำหรับผู้ป่วยแต่ละคนจะบันทึกว่าได้รับการผ่าตัดภายในวันแรกหลังรับไว้ในโรงพยาบาลหรือไม่ ซึ่งในบทความนี้เรียกว่าการผ่าตัดเร็ว (early surgery) และบันทึกว่ามีภาวะสับสนเฉียบพลันหลังผ่าตัด (delirium) ตามมาหรือไม่ ทะเบียนนี้เป็นของสมมติและข้อมูลเป็นข้อมูลจำลอง
ผู้ป่วย 950 คนในการทดลองแบบสุ่มขนาดเล็กที่อยู่ภายในทะเบียนถูกแยกไว้ต่างหาก นักวิเคราะห์ศึกษาผู้ป่วยที่เหลืออีก 19,050 คน ซึ่งแพทย์เป็นผู้เลือกเวลาผ่าตัดให้ ผู้ป่วยที่เปราะบาง (frail) และผู้ที่มีภาวะสมองเสื่อมหรือใช้ยากันเลือดแข็งตัวมักต้องรอนานกว่า การวิเคราะห์จึงถ่วงน้ำหนักการเปรียบเทียบเพื่อให้ความต่างเหล่านี้สมดุล โดยรวมแล้ว อัตราส่วนความเสี่ยง (risk ratio) ของภาวะสับสนเฉียบพลันแบบถ่วงน้ำหนักสำหรับการผ่าตัดเร็วคือ 0.92 (ช่วงเชื่อมั่น 95% คือ 0.86 ถึง 0.97) ซึ่งจะเป็นประโยชน์เพียงเล็กน้อย หากการถ่วงน้ำหนักขจัดตัวกวน (confounding) ได้ครบทุกตัว
จากนั้น การสำรวจเบื้องต้นตามระดับอัลบูมิน (albumin) ในเลือด ซึ่งเป็นโปรตีนที่มักอ่านเป็นตัวชี้วัดภาวะโภชนาการและสุขภาพโดยรวม พบผลที่น่าทึ่ง ในผู้ป่วยที่มีอัลบูมินสูงกว่า 37.8 g/L ซึ่งเป็นหนึ่งในสามส่วนบนของค่าที่บันทึกไว้ อัตราส่วนความเสี่ยงแบบถ่วงน้ำหนักคือ 0.68 (ช่วงเชื่อมั่น 95% คือ 0.57 ถึง 0.83) ส่วนในหนึ่งในสามส่วนล่างคือ 0.96
หกเดือนต่อมา ร่างบทนำเขียนว่า "เราตั้งสมมติฐานว่าผู้ป่วยที่มีภาวะโภชนาการดีจะได้ประโยชน์จากการผ่าตัดเร็วมากที่สุด" ไม่มีใครเคยเขียนสมมติฐานนั้นไว้ก่อนเปิดข้อมูล
การสำรวจข้อมูลคือที่มาของสมมติฐาน
การดูข้อมูลโดยไม่มีสมมติฐานที่กำหนดไว้ก่อนเป็นส่วนปกติและมีคุณค่าของการวิจัย การวิเคราะห์เชิงสำรวจ (exploratory analysis) คือการค้นหารูปแบบในข้อมูลที่น่าศึกษาต่อ ส่วน การวิเคราะห์เพื่อยืนยัน (confirmatory analysis) คือการทดสอบสมมติฐานที่ระบุไว้พร้อมแผนการวิเคราะห์ก่อนเห็นข้อมูล
การวิเคราะห์กลุ่มย่อย (subgroup analysis) คือการประมาณผลแยกภายในกลุ่มผู้ป่วยที่แบ่งตามลักษณะที่วัดก่อนการรักษา เช่นช่วงอายุหรือความเปราะบาง เมื่อผลที่วัดบนมาตรที่ระบุไว้ เช่นอัตราส่วนความเสี่ยงหรืออัตราส่วนออดส์ ต่างกันจริงระหว่างกลุ่มเหล่านั้น ลักษณะนั้นคือตัวปรับผล (effect modifier) และสถานการณ์นี้เรียกว่าการปรับผล (effect modification) การหาตัวปรับผลที่เป็นไปได้จากการสำรวจทะเบียนเป็นจุดเริ่มต้นที่ดี ปัญหาจะเกิดก็ต่อเมื่อบทความระบุผิดว่าความคิดนั้นเกิดขึ้นเมื่อใด
HARKing: การเขียนใหม่ว่าสมมติฐานเกิดขึ้นเมื่อใด
HARKing ย่อมาจาก hypothesizing after the results are known หรือการตั้งสมมติฐานหลังรู้ผล Kerr นิยามว่าคือการนำเสนอสมมติฐานแบบ post hoc ซึ่งเป็นสมมติฐานที่อาศัยหรือได้แนวคิดจากผล ในรายงานวิจัยราวกับเป็นสมมติฐานแบบ a priori ซึ่งเป็นสมมติฐานที่ระบุไว้ล่วงหน้า [1] Rubin อธิบายว่ามีสามรูปแบบ ได้แก่ การสร้างสมมติฐานจากผล การหยิบสมมติฐานจากเอกสารวิชาการมาภายหลัง และการทิ้งสมมติฐานล่วงหน้าที่ผลไม่สนับสนุน [2] ทั้งสามแบบซ่อนว่าสมมติฐานแต่ละข้อเข้ามาอยู่ในบทความเมื่อใดและเพราะอะไร
ร่างในฉากเปิดแสดงรูปแบบแรก ข้อมูลนำไปสู่ผลของอัลบูมิน และผลนำไปสู่สมมติฐาน แต่ต้นฉบับเล่าเรื่องย้อนลำดับ คือสมมติฐาน แล้วการศึกษา แล้วผล ผู้อ่านที่เชื่อลำดับนั้นจะมองสิ่งที่ได้จากการค้นหาเสมือนว่าผ่านการทดสอบมาแล้ว
ทำไมจึงทำให้เข้าใจผิด: ภาวะหลายการทดสอบ
เมื่อการผ่าตัดเร็วไม่มีผลเลย การทดสอบที่ระดับ 5% ก็ยังให้ค่า P ต่ำกว่า 0.05 ด้วยความน่าจะเป็น 0.05 ภาวะหลายการทดสอบ (multiplicity) คือปัญหาจากการทดสอบแบบนี้หลายครั้ง คือโอกาสที่อย่างน้อยหนึ่งครั้งจะเป็นผลบวกลวง (false positive) เพิ่มขึ้นตามจำนวนครั้ง ความน่าจะเป็นที่จะเกิดผลบวกลวงอย่างน้อยหนึ่งครั้งในการทดสอบทั้งชุดคืออัตราความคลาดเคลื่อนทั้งชุดการทดสอบ (family-wise error rate) HARKing ซ่อนขนาดของชุดนั้น เพราะบทความรายงานเพียงหนึ่งสมมติฐานและหนึ่งการทดสอบ
ตัวอย่างคำนวณด้วยมือ: มองยี่สิบครั้งในโลกที่ไม่มีผลจริง
ตัวอย่างคำนวณด้วยมือ นักวิเคราะห์ดูกลุ่มย่อย 20 กลุ่มในโลกที่การผ่าตัดเร็วไม่มีผลต่อใครเลย ให้ถือว่า 20 ครั้งนี้เป็นอิสระต่อกัน และนับว่าการมองครั้งหนึ่งเป็น "ข้อค้นพบ" เมื่อค่า P ต่ำกว่า 0.05
-
มองหนึ่งครั้งเมื่อไม่มีผล
\[ 1 - 0.05 = 0.95 \]
การมองครั้งเดียวให้ค่า P เท่ากับ 0.05 หรือมากกว่าด้วยความน่าจะเป็น 0.95
-
มอง 20 ครั้งโดยไม่พบข้อค้นพบเลย
\[ 0.95^{20} = 0.358 \]
ความน่าจะเป็นของเหตุการณ์อิสระคูณกัน ดังนั้นทั้ง 20 ครั้งจะมีค่า P เท่ากับ 0.05 หรือมากกว่าด้วยความน่าจะเป็น 0.358
-
พบข้อค้นพบอย่างน้อยหนึ่งครั้ง
\[ 1 - 0.95^{20} = 1 - 0.358 = 0.64 \]
โอกาสที่จะพบข้อค้นพบลวงอย่างน้อยหนึ่งครั้งคือส่วนเติมเต็ม เท่ากับ 0.64
-
จำนวนข้อค้นพบที่คาดไว้
\[ 20 \times 0.05 = 1 \]
โดยเฉลี่ยนักวิเคราะห์จะได้ข้อค้นพบลวงหนึ่งครั้งต่อการมอง 20 ครั้ง
ผลลัพธ์: เมื่อมอง 20 ครั้งอย่างอิสระต่อกันและไม่มีผลจริงเลย อัตราความคลาดเคลื่อนทั้งชุดการทดสอบคือ 0.64 หรือ 64% ไม่ใช่ 5%
การมองกลุ่มย่อยจริงซ้อนทับกัน จึงไม่เป็นอิสระต่อกัน และตัวเลขที่แน่นอนจะต่างออกไป แต่จะไม่ต่ำกว่า 0.05 ของการมองครั้งเดียว
ความผิดพลาดสองอย่างที่มักมาคู่กับ HARKing
อย่างหนึ่งเปลี่ยนการวิเคราะห์ อีกอย่างเปลี่ยนถ้อยคำ
p-hacking: เลือกการวิเคราะห์จากค่า P
การปั่นค่า p (p-hacking) คือการลองวิเคราะห์หลายแบบจนมีแบบหนึ่งข้ามเกณฑ์นัยสำคัญ แล้วรายงานเฉพาะแบบนั้น Simmons และคณะแสดงด้วยการจำลองว่า การตัดสินใจธรรมดาไม่กี่อย่างที่ไม่เปิดเผย เช่นเลือกรายงานผลลัพธ์ใดหรือหยุดรับผู้เข้าร่วมเมื่อใด สามารถดันอัตราผลบวกลวงให้สูงกว่าระดับ 5% ที่ตั้งไว้ได้มาก [3] p-hacking ดัดการวิเคราะห์ให้เข้าหาผล ส่วน HARKing ดัดสมมติฐานให้เข้ากับผล
การเกริ่นเชิงเหตุและผลเกินจริง: เขียนความสัมพันธ์ให้เป็นผลของการรักษา
การเกริ่นเชิงเหตุและผลเกินจริง (causal spin) คือการเขียนความสัมพันธ์ให้ฟังเป็นผลของการรักษา การวิเคราะห์ทะเบียนแบบถ่วงน้ำหนักพบภาวะสับสนเฉียบพลันน้อยลงหลังการผ่าตัดเร็ว แล้วส่วนอภิปรายเขียนว่าการผ่าตัดเร็วป้องกันภาวะสับสนเฉียบพลัน นั่นเป็นข้ออ้างเกี่ยวกับสิ่งที่จะเกิดขึ้นเมื่อมีการแทรกแซง
ข้ออ้างเช่นนี้จริงได้ก็ต่อเมื่อข้อสมมติเบื้องหลังค่าประมาณเป็นจริง เช่นไม่มีตัวกวนที่ไม่ได้วัด Hernán เสนอว่าทางแก้ไม่ใช่การเลี่ยงคำเชิงเหตุและผล แต่คือการระบุคำถามเชิงเหตุและผลอย่างเปิดเผย พร้อมข้อสมมติที่ทำให้ค่าประมาณตอบคำถามนั้นได้ [4]
ทางแยกของการวิเคราะห์
ภาวะหลายการทดสอบเกิดได้แม้รันการวิเคราะห์เพียงแบบเดียว ซึ่ง Gelman และ Loken เรียกสถานการณ์นี้ว่าทางแยกของการวิเคราะห์ (garden of forking paths) [5] การเลือกกลุ่มย่อย จุดตัด นิยามผลลัพธ์ หรือชุดตัวแปรปรับแต่ละอย่างเป็นทางแยกหนึ่งแห่ง เมื่อการเลือกเหล่านั้นตามข้อมูล การวิเคราะห์เดียวที่รันจึงถูกข้อมูลเลือกให้ ค่า P ของมันจึงประเมินหลักฐานสูงเกินจริง แม้จะไม่ได้ลองอย่างอื่นเลย
ทะเบียนนี้มีทางแยกเช่นนั้นมากมาย เช่นอายุตัดที่ 80, 85 หรือ 90 ปี หรือแบ่งเป็นช่วง และอัลบูมินแบ่งเป็นสามส่วนหรือตัดที่ 35 หรือ 30 g/L แต่ละแบบให้ค่า P ต่างกัน
วิดเจ็ตด้านล่างให้คุณเดินในสวนแบบนี้ในโลกจำลองที่การผ่าตัดเร็วไม่มีผล แผงแสดงจำนวนเส้นทางที่คุณเดิน เขียนแทนด้วย $k$ และจำนวนที่ได้ค่า P ต่ำกว่า 0.05 โดยแสดงจำนวนนั้นเทียบกับ $0.05 \times k$ ซึ่งเป็นจำนวนที่คาดว่าจะเกิดจากความบังเอิญ และเทียบกับ $1 - 0.95^{k}$ ซึ่งเป็นโอกาสที่จะพบข้อค้นพบลวงอย่างน้อยหนึ่งครั้ง หาก $k$ เส้นทางเป็นอิสระต่อกัน
การแบ่งกลุ่มย่อยที่ประกาศไว้ยี่สิบแบบในทะเบียนจำลอง
บทความนี้วิเคราะห์ผู้ป่วยกลุ่มเดิม 19,050 คนอีกครั้ง ด้วยรายการแบ่งกลุ่มย่อยที่ประกาศไว้ 20 แบบ ซึ่งเขียนไว้ก่อนการวิเคราะห์ซ้ำนี้จะรัน แต่หลังการสำรวจอัลบูมิน รายการนี้แสดงชุดทั้งหมดที่ร่างบทนำละไว้ มันรวมอัลบูมินสามส่วนด้วย และสำหรับการแบ่งแบบนั้น การวิเคราะห์ซ้ำเป็นการมองซ้ำที่เปิดเผย ไม่ใช่การยืนยัน เพราะการยืนยันต้องใช้ข้อมูลที่สมมติฐานไม่ได้มาจาก ต่างจากตัวอย่างคำนวณด้วยมือ ในทะเบียนนี้การผ่าตัดเร็วมีผลจริง และลักษณะหนึ่งคือความเปราะบางเปลี่ยนอัตราส่วนออดส์ของมัน
ASA ระดับ 3 ขึ้นไป ซึ่งใช้ในหลายการแบ่ง หมายถึงโรคทางระบบที่รุนแรงตามการจัดระดับสภาพร่างกายของวิสัญญี แต่ละระดับได้อัตราส่วนความเสี่ยงของภาวะสับสนเฉียบพลันแบบถ่วงน้ำหนักของตัวเอง เทียบการผ่าตัดเร็วกับการผ่าตัดช้ากว่า นี่คือผลเฉลี่ยของการรักษาในประชากรทั้งหมด (average treatment effect, ATE) คือความเสี่ยงหากผู้ป่วยทุกคนในระดับนั้นได้รับการผ่าตัดเร็ว หารด้วยความเสี่ยงหากทุกคนได้รับการผ่าตัดช้ากว่า แต่ละการแบ่งได้ค่า P หนึ่งค่าสำหรับความต่างของอัตราส่วนความเสี่ยงระหว่างระดับ จากการทดสอบที่เปรียบเทียบลอการิทึมของอัตราส่วนความเสี่ยงของระดับเหล่านั้น
การถ่วงน้ำหนักคือการถ่วงน้ำหนักด้วยส่วนกลับของความน่าจะเป็นในการได้รับการรักษา (inverse probability of treatment weighting, IPTW) ผู้ป่วยแต่ละคนนับเป็นส่วนกลับของความน่าจะเป็นที่ประมาณได้ของเวลาผ่าตัดที่เขาได้รับ กลุ่มที่ถ่วงน้ำหนักแล้วจึงสมดุลกันในลักษณะที่อยู่ในแบบจำลองคะแนนแนวโน้ม (propensity model) ซึ่งเป็นแบบจำลองที่ประมาณความน่าจะเป็นเหล่านั้น คู่มือ IPTW ฉบับแยก อธิบายวิธีสร้างและตรวจน้ำหนัก
การแบ่งกลุ่มย่อยที่ประกาศไว้ทั้ง 20 แบบ
| การแบ่งกลุ่มย่อย | อัตราส่วนความเสี่ยง (ช่วงเชื่อมั่น 95%) แยกตามระดับ (อัลบูมินหน่วย g/L) | ค่า P สำหรับความต่างของอัตราส่วนความเสี่ยงระหว่างระดับ |
|---|---|---|
| เพศ | ชาย: 1.00 (0.89 ถึง 1.12); หญิง: 0.88 (0.83 ถึง 0.94) | 0.0540 |
| อายุ ตัดที่ 80 ปี | ต่ำกว่า 80: 0.88 (0.80 ถึง 0.97); 80 ขึ้นไป: 0.92 (0.87 ถึง 0.98) | 0.4035 |
| อายุ ตัดที่ 85 ปี | ต่ำกว่า 85: 0.89 (0.83 ถึง 0.95); 85 ขึ้นไป: 0.93 (0.87 ถึง 0.99) | 0.4511 |
| อายุ ตัดที่ 90 ปี | ต่ำกว่า 90: 0.90 (0.85 ถึง 0.95); 90 ขึ้นไป: 0.94 (0.88 ถึง 1.02) | 0.2930 |
| อายุ สามช่วง | ต่ำกว่า 75: 0.88 (0.77 ถึง 1.01); 75 ถึง 84: 0.90 (0.84 ถึง 0.97); 85 ขึ้นไป: 0.93 (0.87 ถึง 0.99) | 0.7982 |
| อายุ แบ่งตามทศวรรษ | ต่ำกว่า 70: 0.96 (0.78 ถึง 1.18); 70 ถึง 79: 0.86 (0.78 ถึง 0.95); 80 ถึง 89: 0.91 (0.85 ถึง 0.98); 90 ขึ้นไป: 0.94 (0.88 ถึง 1.02) | 0.5039 |
| ระดับ ASA | 1 หรือ 2: 0.90 (0.77 ถึง 1.07); 3 ขึ้นไป: 0.91 (0.87 ถึง 0.97) | 0.8911 |
| ยากันเลือดแข็งตัว | ไม่ใช้: 0.93 (0.88 ถึง 0.98); ใช้: 0.95 (0.76 ถึง 1.19) | 0.8310 |
| ภาวะสมองเสื่อม | ไม่มี: 0.86 (0.80 ถึง 0.93); มี: 0.96 (0.92 ถึง 1.01) | 0.0160 |
| ความเปราะบาง | ไม่เปราะบาง: 0.65 (0.58 ถึง 0.73); เปราะบาง: 1.02 (0.97 ถึง 1.07) | ต่ำกว่า 0.001 |
| อัลบูมิน แบ่งสามส่วน | 34.0 หรือต่ำกว่า: 0.96 (0.90 ถึง 1.04); มากกว่า 34.0 ถึง 37.8: 0.90 (0.71 ถึง 1.13); มากกว่า 37.8: 0.68 (0.57 ถึง 0.83) | 0.0043 |
| อัลบูมิน ตัดที่ 35 g/L | ต่ำกว่า 35: 0.97 (0.89 ถึง 1.06); 35 ขึ้นไป: 0.74 (0.65 ถึง 0.84) | 0.0006 |
| อัลบูมิน ตัดที่ 30 g/L | ต่ำกว่า 30: 0.94 (0.84 ถึง 1.06); 30 ขึ้นไป: 0.89 (0.80 ถึง 0.98) | 0.4366 |
| มีบันทึกอัลบูมินหรือไม่ | ไม่มีบันทึก: 0.94 (0.88 ถึง 1.01); มีบันทึก: 0.90 (0.82 ถึง 0.98) | 0.3644 |
| เพศคูณอายุ 80 ปี | ชายอายุต่ำกว่า 80: 0.95 (0.81 ถึง 1.11); ชายอายุ 80 ขึ้นไป: 1.03 (0.91 ถึง 1.17); หญิงอายุต่ำกว่า 80: 0.86 (0.77 ถึง 0.96); หญิงอายุ 80 ขึ้นไป: 0.88 (0.83 ถึง 0.94) | 0.1131 |
| เพศคูณระดับ ASA | ชาย ASA 1 หรือ 2: 1.07 (0.76 ถึง 1.50); ชาย ASA 3 ขึ้นไป: 0.99 (0.90 ถึง 1.08); หญิง ASA 1 หรือ 2: 0.82 (0.73 ถึง 0.91); หญิง ASA 3 ขึ้นไป: 0.89 (0.83 ถึง 0.95) | 0.0533 |
| เพศคูณภาวะสมองเสื่อม | ชายที่ไม่มีภาวะสมองเสื่อม: 0.88 (0.78 ถึง 1.00); ชายที่มีภาวะสมองเสื่อม: 1.08 (1.01 ถึง 1.15); หญิงที่ไม่มีภาวะสมองเสื่อม: 0.85 (0.78 ถึง 0.93); หญิงที่มีภาวะสมองเสื่อม: 0.91 (0.86 ถึง 0.96) | ต่ำกว่า 0.001 |
| ภาวะสมองเสื่อมคูณระดับ ASA | ไม่มีทั้งสองอย่าง: 0.83 (0.71 ถึง 0.97); ASA 3 ขึ้นไปอย่างเดียว: 0.87 (0.80 ถึง 0.95); สมองเสื่อมอย่างเดียว: 0.94 (0.81 ถึง 1.08); มีทั้งสองอย่าง: 0.97 (0.93 ถึง 1.02) | 0.0581 |
| ยากันเลือดแข็งตัวคูณระดับ ASA | ไม่มีทั้งสองอย่าง: 0.87 (0.79 ถึง 0.95); ASA 3 ขึ้นไปอย่างเดียว: 0.94 (0.89 ถึง 1.00); ใช้ยากันเลือดแข็งตัวอย่างเดียว: 1.65 (0.89 ถึง 3.07); มีทั้งสองอย่าง: 0.86 (0.75 ถึง 0.99) | 0.0985 |
| อายุ 80 ปีคูณภาวะสมองเสื่อม | ต่ำกว่า 80 ไม่มีภาวะสมองเสื่อม: 0.82 (0.71 ถึง 0.94); ต่ำกว่า 80 มีภาวะสมองเสื่อม: 0.95 (0.85 ถึง 1.05); 80 ขึ้นไปไม่มีภาวะสมองเสื่อม: 0.88 (0.81 ถึง 0.96); 80 ขึ้นไปมีภาวะสมองเสื่อม: 0.96 (0.92 ถึง 1.01) | 0.0654 |
แบบจำลองที่ใช้สร้างข้อมูลบอกอะไร
เพราะข้อมูลเป็นข้อมูลจำลอง จึงรู้ค่าจริง ในแบบจำลองที่สร้างภาวะสับสนเฉียบพลัน การผ่าตัดเร็วคูณออดส์ของภาวะสับสนเฉียบพลันด้วย 0.50 ในผู้ป่วยที่ไม่เปราะบาง และด้วย 1.00 ในผู้ป่วยที่เปราะบาง ไม่มีลักษณะอื่นเข้ามาอยู่ในพจน์การผ่าตัดของแบบจำลองนั้น ความเปราะบางจึงเป็นตัวปรับอัตราส่วนออดส์ของการผ่าตัดเร็วเพียงตัวเดียว
ทั่วทั้งประชากรจำลองเบื้องหลังทะเบียน รวมผู้ป่วยในการทดลองด้วย การผ่าตัดเร็วลดความเสี่ยงจริงของภาวะสับสนเฉียบพลันจาก 0.157 เป็น 0.092 ในผู้ป่วยที่ไม่เปราะบาง คิดเป็นอัตราส่วนความเสี่ยง 0.59 ในผู้ป่วยที่เปราะบาง ความเสี่ยงจริงคือ 0.561 ไม่ว่าจะผ่าตัดเร็วหรือไม่ คิดเป็นอัตราส่วนความเสี่ยง 1.00 การแบ่งตามความเปราะบาง ซึ่งประมาณในผู้ป่วยนอกการทดลอง กู้รูปแบบนี้กลับมาได้ด้วยค่า P ต่ำกว่า 0.001 อัตราส่วนความเสี่ยงของมันคือ 0.65 (ช่วงเชื่อมั่น 95% คือ 0.58 ถึง 0.73) ในผู้ป่วยที่ไม่เปราะบาง และ 1.02 (0.97 ถึง 1.07) ในผู้ป่วยที่เปราะบาง ซึ่งช่วงทั้งสองครอบคลุมค่าจริงทั้งคู่
ทำไมอีกสี่การแบ่งจึงได้ค่า P ต่ำกว่า 0.05 ด้วย
อีกสี่การแบ่งได้ค่า P ต่ำกว่า 0.05 ได้แก่ ภาวะสมองเสื่อม อัลบูมินแบ่งสามส่วน อัลบูมินตัดที่ 35 g/L และเพศคูณภาวะสมองเสื่อม สี่การแบ่งนี้ไม่ใช่ข้อค้นพบจากความบังเอิญ แต่ในแบบจำลองที่ใช้สร้างข้อมูล ไม่มีทั้งภาวะสมองเสื่อม อัลบูมิน หรือเพศที่เปลี่ยนอัตราส่วนออดส์ของการผ่าตัดเร็ว ความเปราะบางทำให้เกิดภาวะสมองเสื่อมได้มากขึ้นและทำให้อัลบูมินต่ำลง การแบ่งเหล่านี้จึงแยกผู้ป่วยเปราะบางไว้ในแต่ละระดับไม่เท่ากัน ระดับที่มีผู้ป่วยเปราะบางมากกว่า เช่นมีภาวะสมองเสื่อมหรืออัลบูมินต่ำ จะมีอัตราส่วนความเสี่ยงใกล้ 1 มากกว่า เพราะผู้ป่วยในระดับนั้นมากกว่าที่ไม่ได้ประโยชน์จากการผ่าตัดเร็ว
มาตรอัตราส่วนความเสี่ยงเพิ่มช่องว่างเหล่านี้ แบบจำลองที่ใช้สร้างข้อมูลกำหนดอัตราส่วนออดส์ไว้ค่าหนึ่ง และอัตราส่วนออดส์คงที่ให้อัตราส่วนความเสี่ยงใกล้ตัวมันเองเมื่อภาวะสับสนเฉียบพลันพบน้อย และใกล้ 1 มากขึ้นเมื่อพบบ่อย ภาวะสมองเสื่อมเพิ่มความเสี่ยงของภาวะสับสนเฉียบพลันเมื่อไม่ผ่าตัดเร็ว และอัลบูมินที่สูงกว่าลดความเสี่ยงนั้น ระดับของมันจึงต่างกันจริงในอัตราส่วนความเสี่ยงแม้ในผู้ป่วยที่ไม่เปราะบาง ซึ่งคือการปรับผลบนมาตรอัตราส่วนความเสี่ยง ผลต่างกันระหว่างกลุ่มหรือไม่ขึ้นกับมาตรที่ใช้วัด ซึ่งเป็นคำถามที่ขยายความต่อในบทความแยกเรื่องปฏิกิริยาสัมพันธ์และมาตรวัด (บทความภาษาอังกฤษ)
อ่านเป็นเรื่องเล่า การแบ่งตามอัลบูมินชวนให้เกิดสมมติฐานเรื่องโภชนาการที่ร่างบทนำเขียนไว้ ในโลกจำลองนี้เรื่องเล่านั้นผิด อัลบูมินไม่ได้เปลี่ยนอัตราส่วนออดส์ของการผ่าตัดเร็วในผู้ป่วยคนใดเลย การแบ่งตามอัลบูมินเป็นเพียงตัวแทนของความเปราะบางและความต่างของความเสี่ยงพื้นฐาน กลุ่มย่อยนั้นเป็นรูปแบบที่มีจริง แต่เป็นคำอธิบายที่ผิด
เกือบถึงเกณฑ์ และระดับเดี่ยวที่ดูโดดเด่น
สองการแบ่งพลาดเกณฑ์ไปอย่างหวุดหวิด คือเพศ ที่ค่า P เท่ากับ 0.0540 และเพศคูณระดับ ASA ที่ค่า P เท่ากับ 0.0533 เพศไม่มีบทบาทในการสร้างภาวะสับสนเฉียบพลัน และไม่เกี่ยวกับความเปราะบางหรือสาเหตุอื่นของภาวะสับสนเฉียบพลันในโลกนี้ ชายและหญิงจึงมีอัตราส่วนความเสี่ยงจริงเท่ากัน ช่องว่างระหว่างชาย (1.00) และหญิง (0.88) เกิดจากความบังเอิญล้วน ๆ ทางแยกที่ต่างออกไปเล็กน้อยอาจพาการแบ่งแบบนี้ข้าม 0.05 ได้ และบทความที่ HARKing จะอธิบายมันทันที
ชายที่มีภาวะสมองเสื่อมมีอัตราส่วนความเสี่ยง 1.08 (ช่วงเชื่อมั่น 95% คือ 1.01 ถึง 1.15) ซึ่งเป็นช่วงที่อยู่สูงกว่า 1 ทั้งช่วง แต่ในโลกนี้การผ่าตัดเร็วเพิ่มความเสี่ยงต่อภาวะสับสนเฉียบพลันของใครไม่ได้ เพราะอัตราส่วนออดส์จริงของมันเป็น 0.50 หรือ 1.00 สำหรับผู้ป่วยทุกคน เมื่อในตารางมีช่วงของแต่ละระดับหลายสิบช่วง คาดได้ว่าบางช่วงจะพลาดค่าจริงด้วยความบังเอิญล้วน ๆ และนี่คือหนึ่งในนั้น
Stata: ลูปเดียววนผ่านการแบ่งกลุ่มย่อยที่ประกาศไว้ 20 แบบ
local splits sex age_80 age_85 age_90 age_band3 age_decade asa3 anticoag dementia frail
local splits `splits' albumin_tertile albumin_35 albumin_30 albumin_recorded
local splits `splits' sex_age80 sex_asa3 sex_dementia dementia_asa3 anticoag_asa3 age80_dementia
local lv_sex male female
local lv_age_80 lt80 ge80
local lv_age_85 lt85 ge85
local lv_age_90 lt90 ge90
local lv_age_band3 lt75 75to84 ge85
local lv_age_decade lt70 70to79 80to89 ge90
local lv_asa3 no yes
local lv_anticoag no yes
local lv_dementia no yes
local lv_frail no yes
local lv_albumin_tertile t1 t2 t3
local lv_albumin_35 lt35 ge35
local lv_albumin_30 lt30 ge30
local lv_albumin_recorded no yes
local lv_sex_age80 male_lt80 male_ge80 female_lt80 female_ge80
local lv_sex_asa3 male_asa12 male_asa3 female_asa12 female_asa3
local lv_sex_dementia male_nodem male_dem female_nodem female_dem
local lv_dementia_asa3 neither asa3_only dementia_only both
local lv_anticoag_asa3 neither asa3_only anticoag_only both
local lv_age80_dementia lt80_nodem lt80_dem ge80_nodem ge80_dem
local drop_sex female
local drop_asa3 asa3
local drop_anticoag anticoag
local drop_dementia dementia fd
local drop_frail frail fd
local drop_sex_age80 female
local drop_sex_asa3 female asa3
local drop_sex_dementia female dementia fd
local drop_dementia_asa3 dementia fd asa3
local drop_anticoag_asa3 anticoag asa3
local drop_age80_dementia dementia fd
* ---- IPTW risk ratio of delirium within each level, and the P value for a difference between levels ----
* within a split the levels are independent samples: with b the log risk ratio of a level and w = 1/SE^2,
* the Wald chi-squared statistic sum w*b^2 - (sum w*b)^2/sum w has k - 1 df (for two levels it is the
* square of the z statistic (b1 - b2)/sqrt(SE1^2 + SE2^2))
local ps_all age_c age_c2 female frail dementia fd asa3 anticoag
scalar sc_sig = 0
local i = 0
display as text _newline %-18s "split" %-15s "level" %7s "n" %8s "RR" " 95% CI"
foreach s of local splits {
local i = `i' + 1
local terms : list ps_all - drop_`s'
local k : word count `lv_`s''
scalar sc_sw = 0
scalar sc_swb = 0
scalar sc_swb2 = 0
forvalues j = 1/`k' {
local lv : word `j' of `lv_`s''
quietly teffects ipw (delirium) (surg24 `terms', logit) if g_`s' == `j', pomeans
pomrr
matrix RES = nullmat(RES) \ (`i', `j', e(N), exp(scalar(sc_b)), scalar(sc_lb), scalar(sc_ub))
scalar sc_w = 1/scalar(sc_se)^2
scalar sc_sw = scalar(sc_sw) + scalar(sc_w)
scalar sc_swb = scalar(sc_swb) + scalar(sc_w)*scalar(sc_b)
scalar sc_swb2 = scalar(sc_swb2) + scalar(sc_w)*scalar(sc_b)^2
display as text %-18s cond(`j' == 1, "`s'", "") %-15s "`lv'" %7.0f e(N) %8.2f exp(scalar(sc_b)) ///
" " %4.2f scalar(sc_lb) " to " %4.2f scalar(sc_ub)
}
scalar sc_p = chi2tail(`k' - 1, scalar(sc_swb2) - scalar(sc_swb)^2/scalar(sc_sw))
matrix PV = nullmat(PV) \ scalar(sc_p)
scalar sc_sig = scalar(sc_sig) + (scalar(sc_p) < 0.05)
display as text %-18s "" "P for a difference between levels = " %6.4f scalar(sc_p) ///
cond(scalar(sc_p) < 0.05, " (P < 0.05)", "")
}
display as text _newline "splits with P < 0.05: " scalar(sc_sig) " of " `i'
. display as text _newline %-18s "split" %-15s "level" %7s "n" %8s "RR" " 95% CI"
split level n RR 95% CI
. foreach s of local splits {
2. local i = `i' + 1
3. local terms : list ps_all - drop_`s'
4. local k : word count `lv_`s''
5. scalar sc_sw = 0
6. scalar sc_swb = 0
7. scalar sc_swb2 = 0
8. forvalues j = 1/`k' {
9. local lv : word `j' of `lv_`s''
10. quietly teffects ipw (delirium) (surg24 `terms', logit) if g_`s' == `j', pomeans
11. pomrr
12. matrix RES = nullmat(RES) \ (`i', `j', e(N), exp(scalar(sc_b)), scalar(sc_lb), scalar(sc_ub))
13. scalar sc_w = 1/scalar(sc_se)^2
14. scalar sc_sw = scalar(sc_sw) + scalar(sc_w)
15. scalar sc_swb = scalar(sc_swb) + scalar(sc_w)*scalar(sc_b)
16. scalar sc_swb2 = scalar(sc_swb2) + scalar(sc_w)*scalar(sc_b)^2
17. display as text %-18s cond(`j' == 1, "`s'", "") %-15s "`lv'" %7.0f e(N) %8.2f exp(scalar(sc_b)) ///
> " " %4.2f scalar(sc_lb) " to " %4.2f scalar(sc_ub)
18. }
19. scalar sc_p = chi2tail(`k' - 1, scalar(sc_swb2) - scalar(sc_swb)^2/scalar(sc_sw))
20. matrix PV = nullmat(PV) \ scalar(sc_p)
21. scalar sc_sig = scalar(sc_sig) + (scalar(sc_p) < 0.05)
22. display as text %-18s "" "P for a difference between levels = " %6.4f scalar(sc_p) ///
> cond(scalar(sc_p) < 0.05, " (P < 0.05)", "")
23. }
sex male 5665 1.00 0.89 to 1.12
female 13385 0.88 0.83 to 0.94
P for a difference between levels = 0.0540
age_80 lt80 8824 0.88 0.80 to 0.97
ge80 10226 0.92 0.87 to 0.98
P for a difference between levels = 0.4035
age_85 lt85 12075 0.89 0.83 to 0.95
ge85 6975 0.93 0.87 to 0.99
P for a difference between levels = 0.4511
age_90 lt90 14780 0.90 0.85 to 0.95
ge90 4270 0.94 0.88 to 1.02
P for a difference between levels = 0.2930
age_band3 lt75 5787 0.88 0.77 to 1.01
75to84 6288 0.90 0.84 to 0.97
ge85 6975 0.93 0.87 to 0.99
P for a difference between levels = 0.7982
age_decade lt70 3325 0.96 0.78 to 1.18
70to79 5499 0.86 0.78 to 0.95
80to89 5956 0.91 0.85 to 0.98
ge90 4270 0.94 0.88 to 1.02
P for a difference between levels = 0.5039
asa3 no 7674 0.90 0.77 to 1.07
yes 11376 0.91 0.87 to 0.97
P for a difference between levels = 0.8911
anticoag no 15798 0.93 0.88 to 0.98
yes 3252 0.95 0.76 to 1.19
P for a difference between levels = 0.8310
dementia no 14024 0.86 0.80 to 0.93
yes 5026 0.96 0.92 to 1.01
P for a difference between levels = 0.0160 (P < 0.05)
frail no 10899 0.65 0.58 to 0.73
yes 8151 1.02 0.97 to 1.07
P for a difference between levels = 0.0000 (P < 0.05)
albumin_tertile t1 4471 0.96 0.90 to 1.04
t2 4409 0.90 0.71 to 1.13
t3 4270 0.68 0.57 to 0.83
P for a difference between levels = 0.0043 (P < 0.05)
albumin_35 lt35 5494 0.97 0.89 to 1.06
ge35 7656 0.74 0.65 to 0.84
P for a difference between levels = 0.0006 (P < 0.05)
albumin_30 lt30 1242 0.94 0.84 to 1.06
ge30 11908 0.89 0.80 to 0.98
P for a difference between levels = 0.4366
albumin_recorded no 5900 0.94 0.88 to 1.01
yes 13150 0.90 0.82 to 0.98
P for a difference between levels = 0.3644
sex_age80 male_lt80 2647 0.95 0.81 to 1.11
male_ge80 3018 1.03 0.91 to 1.17
female_lt80 6177 0.86 0.77 to 0.96
female_ge80 7208 0.88 0.83 to 0.94
P for a difference between levels = 0.1131
sex_asa3 male_asa12 2223 1.07 0.76 to 1.50
male_asa3 3442 0.99 0.90 to 1.08
female_asa12 5451 0.82 0.73 to 0.91
female_asa3 7934 0.89 0.83 to 0.95
P for a difference between levels = 0.0533
sex_dementia male_nodem 4114 0.88 0.78 to 1.00
male_dem 1551 1.08 1.01 to 1.15
female_nodem 9910 0.85 0.78 to 0.93
female_dem 3475 0.91 0.86 to 0.96
P for a difference between levels = 0.0000 (P < 0.05)
dementia_asa3 neither 6024 0.83 0.71 to 0.97
asa3_only 8000 0.87 0.80 to 0.95
dementia_only 1650 0.94 0.81 to 1.08
both 3376 0.97 0.93 to 1.02
P for a difference between levels = 0.0581
anticoag_asa3 neither 6435 0.87 0.79 to 0.95
asa3_only 9363 0.94 0.89 to 1.00
anticoag_only 1239 1.65 0.89 to 3.07
both 2013 0.86 0.75 to 0.99
P for a difference between levels = 0.0985
age80_dementia lt80_nodem 7411 0.82 0.71 to 0.94
lt80_dem 1413 0.95 0.85 to 1.05
ge80_nodem 6613 0.88 0.81 to 0.96
ge80_dem 3613 0.96 0.92 to 1.01
P for a difference between levels = 0.0654
. display as text _newline "splits with P < 0.05: " scalar(sc_sig) " of " `i'
splits with P < 0.05: 5 of 20
R: ลูปเดียวกันด้วย WeightIt
splits <- list(
sex = list(lv = c("male", "female"), drop = "female"),
age_80 = list(lv = c("lt80", "ge80"), drop = character(0)),
age_85 = list(lv = c("lt85", "ge85"), drop = character(0)),
age_90 = list(lv = c("lt90", "ge90"), drop = character(0)),
age_band3 = list(lv = c("lt75", "75to84", "ge85"), drop = character(0)),
age_decade = list(lv = c("lt70", "70to79", "80to89", "ge90"), drop = character(0)),
asa3 = list(lv = c("no", "yes"), drop = "asa3"),
anticoag = list(lv = c("no", "yes"), drop = "anticoag"),
dementia = list(lv = c("no", "yes"), drop = c("dementia", "fd")),
frail = list(lv = c("no", "yes"), drop = c("frail", "fd")),
albumin_tertile = list(lv = c("t1", "t2", "t3"), drop = character(0)),
albumin_35 = list(lv = c("lt35", "ge35"), drop = character(0)),
albumin_30 = list(lv = c("lt30", "ge30"), drop = character(0)),
albumin_recorded = list(lv = c("no", "yes"), drop = character(0)),
sex_age80 = list(lv = c("male_lt80", "male_ge80", "female_lt80", "female_ge80"), drop = "female"),
sex_asa3 = list(lv = c("male_asa12", "male_asa3", "female_asa12", "female_asa3"), drop = c("female", "asa3")),
sex_dementia = list(lv = c("male_nodem", "male_dem", "female_nodem", "female_dem"),
drop = c("female", "dementia", "fd")),
dementia_asa3 = list(lv = c("neither", "asa3_only", "dementia_only", "both"), drop = c("dementia", "fd", "asa3")),
anticoag_asa3 = list(lv = c("neither", "asa3_only", "anticoag_only", "both"), drop = c("anticoag", "asa3")),
age80_dementia = list(lv = c("lt80_nodem", "lt80_dem", "ge80_nodem", "ge80_dem"), drop = c("dementia", "fd"))
)
# ---- IPTW risk ratio of delirium within each level, and the P value for a difference between levels ----
# within a split the levels are independent samples: with b the log risk ratio of a level and w = 1/SE^2,
# the Wald chi-squared statistic sum w*b^2 - (sum w*b)^2/sum w has k - 1 df (for two levels it is the
# square of the z statistic (b1 - b2)/sqrt(SE1^2 + SE2^2))
ps_all <- c("age_c", "age_c2", "female", "frail", "dementia", "fd", "asa3", "anticoag")
cat(sprintf("\n%-18s%-15s%7s%8s 95%% CI\n", "split", "level", "n", "RR"))
res <- lapply(names(splits), function(s) {
sp <- splits[[s]]
f_ps <- reformulate(setdiff(ps_all, sp$drop), response = "surg24")
rows <- lapply(seq_along(sp$lv), function(j) {
dj <- d0[!is.na(d0[[paste0("g_", s)]]) & d0[[paste0("g_", s)]] == j, ]
W <- weightit(f_ps, data = dj, method = "glm", estimand = "ATE")
fit <- glm_weightit(delirium ~ surg24, data = dj, weightit = W, family = quasipoisson(link = "log"))
b <- coef(fit)[["surg24"]]; se <- sqrt(vcov(fit)["surg24", "surg24"])
cat(sprintf("%-18s%-15s%7d%8.2f %4.2f to %4.2f\n", if (j == 1) s else "", sp$lv[j], nrow(dj),
exp(b), exp(b - z * se), exp(b + z * se)))
data.frame(split = s, level = sp$lv[j], n = nrow(dj), rr = exp(b), lb = exp(b - z * se),
ub = exp(b + z * se), b = b, se = se)
})
r <- do.call(rbind, rows)
w <- 1 / r$se^2
p <- pchisq(sum(w * r$b^2) - sum(w * r$b)^2 / sum(w), df = nrow(r) - 1, lower.tail = FALSE)
cat(sprintf("%-18sP for a difference between levels = %6.4f%s\n", "", p,
if (p < 0.05) " (P < 0.05)" else ""))
list(levels = r, p = p)
})
names(res) <- names(splits)
sig <- sum(sapply(res, function(x) x$p < 0.05))
cat(sprintf("\nsplits with P < 0.05: %d of %d\n", sig, length(res)))
> cat(sprintf("\n%-18s%-15s%7s%8s 95%% CI\n", "split",
+ "level", "n", "RR"))
split level n RR 95% CI
> res <- lapply(names(splits), function(s) {
+ sp <- splits[[s]]
+ f_ps <- reformulate(setdiff(ps_all, sp$drop), response = "surg24")
+ rows <- lapply(seq_along(sp$lv), function(j) {
+ dj <- d0[!is.na(d0[[paste0("g_", s)]]) & d0[[paste0("g_",
+ s)]] == j, ]
+ W <- weightit(f_ps, data = dj, method = "glm", estimand = "ATE")
+ fit <- glm_weightit(delirium ~ surg24, data = dj, weightit = W,
+ family = quasipoisson(link = "log"))
+ b <- coef(fit)[["surg24"]]
+ se <- sqrt(vcov(fit)["surg24", "surg24"])
+ cat(sprintf("%-18s%-15s%7d%8.2f %4.2f to %4.2f\n",
+ if (j == 1)
+ s
+ else "", sp$lv[j], nrow(dj), exp(b), exp(b - z *
+ se), exp(b + z * se)))
+ data.frame(split = s, level = sp$lv[j], n = nrow(dj),
+ rr = exp(b), lb = exp(b - z * se), ub = exp(b + z *
+ se), b = b, se = se)
+ })
+ r <- do.call(rbind, rows)
+ w <- 1/r$se^2
+ p <- pchisq(sum(w * r$b^2) - sum(w * r$b)^2/sum(w), df = nrow(r) -
+ 1, lower.tail = FALSE)
+ cat(sprintf("%-18sP for a difference between levels = %6.4f%s\n",
+ "", p, if (p < 0.05)
+ " (P < 0.05)"
+ else ""))
+ list(levels = r, p = p)
+ })
sex male 5665 1.00 0.89 to 1.12
female 13385 0.88 0.83 to 0.94
P for a difference between levels = 0.0540
age_80 lt80 8824 0.88 0.80 to 0.97
ge80 10226 0.92 0.87 to 0.98
P for a difference between levels = 0.4035
age_85 lt85 12075 0.89 0.83 to 0.95
ge85 6975 0.93 0.87 to 0.99
P for a difference between levels = 0.4511
age_90 lt90 14780 0.90 0.85 to 0.95
ge90 4270 0.94 0.88 to 1.02
P for a difference between levels = 0.2930
age_band3 lt75 5787 0.88 0.77 to 1.01
75to84 6288 0.90 0.84 to 0.97
ge85 6975 0.93 0.87 to 0.99
P for a difference between levels = 0.7982
age_decade lt70 3325 0.96 0.78 to 1.18
70to79 5499 0.86 0.78 to 0.95
80to89 5956 0.91 0.85 to 0.98
ge90 4270 0.94 0.88 to 1.02
P for a difference between levels = 0.5039
asa3 no 7674 0.90 0.77 to 1.07
yes 11376 0.91 0.87 to 0.97
P for a difference between levels = 0.8911
anticoag no 15798 0.93 0.88 to 0.98
yes 3252 0.95 0.76 to 1.19
P for a difference between levels = 0.8310
dementia no 14024 0.86 0.80 to 0.93
yes 5026 0.96 0.92 to 1.01
P for a difference between levels = 0.0160 (P < 0.05)
frail no 10899 0.65 0.58 to 0.73
yes 8151 1.02 0.97 to 1.07
P for a difference between levels = 0.0000 (P < 0.05)
albumin_tertile t1 4471 0.96 0.90 to 1.04
t2 4409 0.90 0.71 to 1.13
t3 4270 0.68 0.57 to 0.83
P for a difference between levels = 0.0043 (P < 0.05)
albumin_35 lt35 5494 0.97 0.89 to 1.06
ge35 7656 0.74 0.65 to 0.84
P for a difference between levels = 0.0006 (P < 0.05)
albumin_30 lt30 1242 0.94 0.84 to 1.06
ge30 11908 0.89 0.80 to 0.98
P for a difference between levels = 0.4366
albumin_recorded no 5900 0.94 0.88 to 1.01
yes 13150 0.90 0.82 to 0.98
P for a difference between levels = 0.3644
sex_age80 male_lt80 2647 0.95 0.81 to 1.11
male_ge80 3018 1.03 0.91 to 1.17
female_lt80 6177 0.86 0.77 to 0.96
female_ge80 7208 0.88 0.83 to 0.94
P for a difference between levels = 0.1131
sex_asa3 male_asa12 2223 1.07 0.76 to 1.50
male_asa3 3442 0.99 0.90 to 1.08
female_asa12 5451 0.82 0.73 to 0.91
female_asa3 7934 0.89 0.83 to 0.95
P for a difference between levels = 0.0533
sex_dementia male_nodem 4114 0.88 0.78 to 1.00
male_dem 1551 1.08 1.01 to 1.15
female_nodem 9910 0.85 0.78 to 0.93
female_dem 3475 0.91 0.86 to 0.96
P for a difference between levels = 0.0000 (P < 0.05)
dementia_asa3 neither 6024 0.83 0.71 to 0.97
asa3_only 8000 0.87 0.80 to 0.95
dementia_only 1650 0.94 0.81 to 1.08
both 3376 0.97 0.93 to 1.02
P for a difference between levels = 0.0581
anticoag_asa3 neither 6435 0.87 0.79 to 0.95
asa3_only 9363 0.94 0.89 to 1.00
Warning in weightit(f_ps, data = dj, method = "glm", estimand = "ATE") :
Some extreme weights were generated. Examine them with `summary()` and maybe
trim them with `trim()`.
anticoag_only 1239 1.65 0.89 to 3.07
both 2013 0.86 0.75 to 0.99
P for a difference between levels = 0.0985
age80_dementia lt80_nodem 7411 0.82 0.71 to 0.94
lt80_dem 1413 0.95 0.85 to 1.05
ge80_nodem 6613 0.88 0.81 to 0.96
ge80_dem 3613 0.96 0.92 to 1.01
P for a difference between levels = 0.0654
> names(res) <- names(splits)
> sig <- sum(sapply(res, function(x) x$p < 0.05))
> cat(sprintf("\nsplits with P < 0.05: %d of %d\n",
+ sig, length(res)))
splits with P < 0.05: 5 of 20
สิ่งที่ทำกับสิ่งที่อ้างได้
ทางแก้ HARKing ไม่ใช่การเงียบเรื่องผลเชิงสำรวจ แต่คือการเขียนผลแต่ละอย่างในระดับที่การออกแบบการศึกษารองรับ
ถ้อยคำที่ซื่อสัตย์ตามสิ่งที่ได้ทำ
| สิ่งที่ทำ | สิ่งที่รองรับได้ | ถ้อยคำที่ซื่อสัตย์ |
|---|---|---|
| ดูข้อมูลโดยไม่มีสมมติฐานล่วงหน้าแล้วสังเกตเห็นรูปแบบ | คำอธิบายข้อมูล | "ในการสำรวจเบื้องต้น อัตราส่วนความเสี่ยงแบบถ่วงน้ำหนักต่ำกว่าในผู้ป่วยที่มีอัลบูมินสูงกว่า" |
| รันการวิเคราะห์ที่เลือกหลังเห็นข้อมูล | สมมติฐานใหม่ที่ต้องทดสอบในข้อมูลอื่น | "การวิเคราะห์เชิงสำรวจแบบ post hoc ชี้ว่า ..." |
| ทดสอบสมมติฐานที่เขียนไว้พร้อมแผนการวิเคราะห์ก่อนเห็นข้อมูล | การทดสอบเพื่อยืนยันสมมติฐานนั้น | "เราทดสอบสมมติฐานที่ระบุไว้ล่วงหน้า (prespecified) ว่า ..." |
| วิเคราะห์ทุกกลุ่มย่อยในรายการที่ประกาศไว้ | ชุดการทดสอบที่อ่านรวมกัน | "จากการวิเคราะห์กลุ่มย่อย 20 แบบในรายการที่ประกาศไว้ 5 แบบมีค่า P ต่ำกว่า 0.05 และรายงานครบทั้ง 20 แบบ" |
| ประมาณผลจากข้อมูลเชิงสังเกตภายใต้ข้อสมมติที่ระบุไว้ | ค่าประมาณของผล หากข้อสมมติเป็นจริง | "โดยสมมติว่าไม่มีตัวกวนที่ไม่ได้วัด การผ่าตัดเร็วถูกประมาณว่า ..." |
| สุ่มการแทรกแซง | หลักฐานโดยตรงที่สุดเกี่ยวกับผล | "การผ่าตัดเร็วลดภาวะสับสนเฉียบพลันในการทดลองนี้" |
มาตรการที่ทำให้การสำรวจยังซื่อสัตย์
การลงทะเบียนแผนการวิเคราะห์ล่วงหน้า (preregistration) คือบันทึกที่มีตราเวลาของสมมติฐานและแผนการวิเคราะห์ ทำไว้ก่อนเห็นข้อมูล [6] มันไม่ได้ห้ามการสำรวจ แต่ทำให้เส้นแบ่งระหว่างการวิเคราะห์ที่วางแผนไว้กับที่ไม่ได้วางแผนมองเห็นได้ และการเปลี่ยนแผนถูกรายงานแทนที่จะถูกซ่อน
ทะเบียนการทดลองและโปรโตคอลที่เผยแพร่ช่วยให้ผู้อ่านเทียบสิ่งที่วางแผนไว้กับสิ่งที่รายงาน การเทียบแบบนี้ครั้งหนึ่งพบว่ามีการรายงานผลลัพธ์แบบเลือกและมีการเปลี่ยนผลลัพธ์หลัก [7] การวิเคราะห์เชิงสังเกตทำตามวินัยเดียวกันได้ด้วยแผนการวิเคราะห์ที่ลงวันที่ไว้ก่อนเปิดข้อมูลผลลัพธ์
เกณฑ์ความน่าเชื่อถือของข้ออ้างเรื่องกลุ่มย่อยให้รายการตรวจ [8] กลุ่มย่อยนั้นเป็นหนึ่งในไม่กี่กลุ่มที่ระบุไว้ล่วงหน้าพร้อมทิศทางที่คาดหรือไม่ การทดสอบปฏิกิริยาสัมพันธ์ (test of interaction) ซึ่งทดสอบว่าผลต่างกันระหว่างระดับหรือไม่ ทำให้ความบังเอิญเป็นคำอธิบายที่เป็นไปได้น้อยหรือไม่ ผลนั้นเป็นอิสระจากผลของกลุ่มย่อยอื่น และคงเส้นคงวาข้ามการศึกษาและผลลัพธ์ที่เกี่ยวข้องหรือไม่
การแบ่งตามภาวะสมองเสื่อมและอัลบูมินในทะเบียนไม่ผ่านคำถามเรื่องความเป็นอิสระ เพราะแต่ละอย่างแฝงความเปราะบาง การคิดจากคำถามเชิงเหตุและผลก่อนก็ช่วยเช่นกัน [4] คือระบุผลที่สนใจและลักษณะที่อาจปรับผลนั้นพร้อมเหตุผล ก่อนจะตรวจกลุ่มย่อยใด ผลแบบ post hoc ที่ผ่านทั้งหมดนี้ก็ยังเป็นเพียงสมมติฐาน จนกว่าข้อมูลใหม่จะยืนยัน
ความเข้าใจผิดที่พบบ่อยและวิธีแก้
-
"การวิเคราะห์แบบ post hoc ไร้ค่าทั้งหมด"
ความผิดในฉากเปิดอยู่ที่บทนำที่เขียนใหม่ ไม่ใช่ที่การสำรวจซึ่งพบรูปแบบของอัลบูมิน
วิธีแก้: การวิเคราะห์แบบ post hoc คือวิธีที่ได้สมมติฐานใหม่ ความผิดพลาดคือการนำเสนอราวกับว่าวางแผนไว้ล่วงหน้า ให้ระบุว่าเป็นการสำรวจ รายงานทุกอย่างที่ตรวจ และทดสอบในข้อมูลใหม่
-
"การแบ่งที่มีค่า P ต่ำที่สุดบอกว่าผลต่างกันตรงไหน"
ห้าการแบ่งได้ค่า P ต่ำกว่า 0.05 แต่มีเพียงความเปราะบางที่เปลี่ยนอัตราส่วนออดส์ของการผ่าตัดเร็ว การแบ่งตามภาวะสมองเสื่อมและอัลบูมินแฝงความเปราะบางและความเสี่ยงพื้นฐานที่ต่างกัน ซึ่งทำให้อัตราส่วนความเสี่ยงเปลี่ยนไป
วิธีแก้: ถามว่าระดับต่าง ๆ ต่างกันที่อะไรอีก ตรวจว่ามาตรของตัวชี้วัดผลสร้างช่องว่างนั้นได้หรือไม่ และเลือกตัวปรับผลที่ระบุไว้ล่วงหน้าพร้อมเหตุผล
-
"ค่า P สูงกว่า 0.05 เล็กน้อยแปลว่าไม่ต่างกัน และต่ำกว่าเล็กน้อยแปลว่าต่างกันจริง"
การแบ่งตามเพศ ที่ค่า P เท่ากับ 0.0540 สะท้อนความบังเอิญล้วน ๆ ส่วนการแบ่งตามภาวะสมองเสื่อม ที่ค่า P เท่ากับ 0.0160 สะท้อนความเปราะบางและความเสี่ยงพื้นฐานที่สูงกว่า การแบ่งตาม ASA ที่ค่า P เท่ากับ 0.8911 ไม่พบช่องว่าง แม้ ASA ระดับสูงกว่าจะมีความเสี่ยงพื้นฐานของภาวะสับสนเฉียบพลันสูงกว่า เกณฑ์ 0.05 จึงแยกการแบ่งที่ความเปราะบางหรือความเสี่ยงพื้นฐานทำให้อัตราส่วนความเสี่ยงเปลี่ยนไปออกจากการแบ่งที่เป็นเพียงความบังเอิญไม่ได้ ในโลกนี้เพศมีอัตราส่วนความเสี่ยงจริงเท่ากันในชายและหญิง ส่วนภาวะสมองเสื่อมและอัลบูมินต่างกันจริงเพราะแฝงความเปราะบาง
วิธีแก้: รายงานค่าประมาณและช่วงของมันสำหรับทุกการแบ่ง และให้การออกแบบและกลไกเป็นตัวตัดสินว่าอะไรควรได้รับการศึกษาต่อ
-
"การแก้ค่าจากภาวะหลายการทดสอบแก้ HARKing ได้"
การแก้ค่าแบบ Bonferroni ซึ่งเทียบค่า P แต่ละค่ากับ 0.05 หารด้วยจำนวนการทดสอบ ควบคุมอัตราความคลาดเคลื่อนทั้งชุดการทดสอบเฉพาะการทดสอบที่ถูกรายงานเท่านั้น
วิธีแก้: เปิดเผยทุกการวิเคราะห์ที่ตรวจ เพราะการแก้ค่าใช้ได้กับชุดที่มองเห็นเท่านั้น
สิ่งที่ควรทำในการวิเคราะห์ของคุณเอง
- ก่อนเปิดข้อมูลผลลัพธ์ ให้เขียนสมมติฐาน ทุกกลุ่มย่อยพร้อมทิศทางที่คาด และการทดสอบปฏิกิริยาสัมพันธ์ แล้วลงวันที่หรือลงทะเบียนแผนนั้น
- ระบุทุกการวิเคราะห์ในบทความว่าระบุไว้ล่วงหน้า (prespecified) หรือ post hoc และรายงานทุกกลุ่มย่อยที่ตรวจ รวมถึงกลุ่มที่ไม่พบอะไร
- ตัดสินกลุ่มย่อยด้วยการทดสอบปฏิกิริยาสัมพันธ์และด้วยค่าประมาณพร้อมช่วงของมัน ไม่ใช่ด้วยค่า P แยกภายในแต่ละระดับ
- พิจารณาจัดการตัวปรับผลที่เป็นไปได้ซึ่งเป็นตัวแปรต่อเนื่อง เช่นอายุหรืออัลบูมิน เป็นตัวแปรต่อเนื่อง แทนที่จะเลือกจุดตัดหลังเห็นข้อมูล
อภิธานศัพท์
- HARKing (การตั้งสมมติฐานหลังรู้ผล)
- การตั้งสมมติฐานหลังรู้ผล (hypothesizing after the results are known): การนำเสนอสมมติฐานที่ตั้งหลังเห็นผลราวกับว่าระบุไว้ล่วงหน้า
- exploratory analysis
- การวิเคราะห์เชิงสำรวจ: การวิเคราะห์ที่ค้นหารูปแบบในข้อมูลที่น่าศึกษาต่อ และให้กำเนิดสมมติฐาน
- confirmatory analysis
- การวิเคราะห์เพื่อยืนยัน: การวิเคราะห์ที่ทดสอบสมมติฐานซึ่งระบุไว้พร้อมแผนการวิเคราะห์ก่อนเห็นข้อมูล
- subgroup analysis
- การวิเคราะห์กลุ่มย่อย: การประมาณผลภายในกลุ่มผู้ป่วยที่แบ่งตามลักษณะที่วัดก่อนการรักษา
- effect modification
- การปรับผล: ความต่างจริงของผลการรักษาระหว่างกลุ่มผู้ป่วย บนมาตรที่ระบุไว้
- multiplicity
- ภาวะหลายการทดสอบ: โอกาสที่จะเกิดผลบวกลวงอย่างน้อยหนึ่งครั้งที่เพิ่มขึ้นเมื่อทดสอบมากขึ้น
- family-wise error
- อัตราความคลาดเคลื่อนทั้งชุดการทดสอบ: ความน่าจะเป็นของผลบวกลวงอย่างน้อยหนึ่งครั้งในการทดสอบทั้งชุด
- p-hacking (การปั่นค่า p)
- การลองวิเคราะห์หลายแบบจนมีแบบหนึ่งข้ามเกณฑ์นัยสำคัญ แล้วรายงานเฉพาะแบบนั้น
- garden of forking paths (ทางแยกของการวิเคราะห์)
- การเลือกวิธีวิเคราะห์ตามข้อมูล ซึ่งทำให้ผลบวกลวงสูงเกินจริงแม้รันการวิเคราะห์เพียงแบบเดียว
- preregistration (การลงทะเบียนแผนการวิเคราะห์ล่วงหน้า)
- บันทึกที่มีตราเวลาของสมมติฐานและแผนการวิเคราะห์ ทำไว้ก่อนเห็นข้อมูล
- average treatment effect (ATE) (ผลเฉลี่ยของการรักษาในประชากรทั้งหมด (ATE))
- ผลเฉลี่ยของการรักษาหากทุกคนในกลุ่มได้รับการรักษา เทียบกับหากไม่มีใครได้รับการรักษา บนมาตรที่ระบุไว้ เช่นอัตราส่วนความเสี่ยง
- inverse probability of treatment weighting (IPTW) (การถ่วงน้ำหนักด้วยส่วนกลับของความน่าจะเป็นในการได้รับการรักษา)
- การถ่วงน้ำหนักผู้ป่วยแต่ละคนด้วยส่วนกลับของความน่าจะเป็นของการรักษาที่เขาได้รับ เพื่อให้กลุ่มที่ถ่วงน้ำหนักแล้วสมดุลกันในลักษณะที่อยู่ในแบบจำลองของความน่าจะเป็นนั้น
เอกสารอ้างอิง
- Kerr NL. HARKing: hypothesizing after the results are known. Pers Soc Psychol Rev. 1998;2(3):196-217. doi:10.1207/s15327957pspr0203_4 https://doi.org/10.1207/s15327957pspr0203_4
- Rubin M. When does HARKing hurt? Identifying when different types of undisclosed post hoc hypothesizing harm scientific progress. Rev Gen Psychol. 2017;21(4):308-320. doi:10.1037/gpr0000128 https://doi.org/10.1037/gpr0000128
- Simmons JP, Nelson LD, Simonsohn U. False-positive psychology: undisclosed flexibility in data collection and analysis allows presenting anything as significant. Psychol Sci. 2011;22(11):1359-1366. doi:10.1177/0956797611417632 https://doi.org/10.1177/0956797611417632
- Hernán MA. The C-word: scientific euphemisms do not improve causal inference from observational data. Am J Public Health. 2018;108(5):616-619. doi:10.2105/AJPH.2018.304337 https://doi.org/10.2105/AJPH.2018.304337
- Gelman A, Loken E. The statistical crisis in science. Am Sci. 2014;102(6):460-465. doi:10.1511/2014.111.460 https://doi.org/10.1511/2014.111.460
- Nosek BA, Ebersole CR, DeHaven AC, Mellor DT. The preregistration revolution. Proc Natl Acad Sci U S A. 2018;115(11):2600-2606. doi:10.1073/pnas.1708274114 https://doi.org/10.1073/pnas.1708274114
- Chan A-W, Hrobjartsson A, Haahr MT, Gotzsche PC, Altman DG. Empirical evidence for selective reporting of outcomes in randomized trials: comparison of protocols to published articles. JAMA. 2004;291(20):2457-2465. doi:10.1001/jama.291.20.2457 https://doi.org/10.1001/jama.291.20.2457
- Sun X, Briel M, Walter SD, Guyatt GH. Is a subgroup effect believable? Updating criteria to evaluate the credibility of subgroup analyses. BMJ. 2010;340:c117. doi:10.1136/bmj.c117 https://doi.org/10.1136/bmj.c117
ประเด็นสำคัญ
- การสำรวจข้อมูลเพื่อหาสมมติฐานใหม่เป็นเรื่องชอบธรรม ส่วน HARKing คือการเขียนใหม่โดยไม่เปิดเผยว่าสมมติฐานเกิดขึ้นเมื่อใด
- เมื่อมอง 20 ครั้งอย่างอิสระต่อกันที่ระดับ 5% และไม่มีผลจริงเลย โอกาสที่จะได้ค่า P ต่ำกว่า 0.05 อย่างน้อยหนึ่งค่าคือ 0.64
- ในทะเบียนจำลอง 5 จาก 20 การแบ่งกลุ่มย่อยที่ประกาศไว้ได้ค่า P ต่ำกว่า 0.05 แต่มีเพียงความเปราะบางที่เปลี่ยนอัตราส่วนออดส์ของการผ่าตัดเร็ว การแบ่งตามภาวะสมองเสื่อมและอัลบูมินแฝงความเปราะบางและความเสี่ยงพื้นฐานที่ต่างกัน ซึ่งทำให้อัตราส่วนความเสี่ยงเปลี่ยนไป
- การเลือกกลุ่มย่อย จุดตัด หรือชุดตัวแปรปรับตามข้อมูลทำให้ข้อค้นพบลวงสูงเกินจริง แม้รันการวิเคราะห์เพียงแบบเดียว
- ลงทะเบียนแผนล่วงหน้า ระบุการวิเคราะห์แบบ post hoc รายงานทุกกลุ่มย่อยที่ตรวจ และยืนยันข้อค้นพบใหม่ในข้อมูลใหม่
อ่านต่อในวิกิ: [[iptw-guide-th]]