สัมประสิทธิ์ตามเวลาใน R - จะทำอย่างไร?


17

อัปเดต : ขออภัยสำหรับการอัปเดตอื่น แต่ฉันพบวิธีแก้ปัญหาที่เป็นไปได้ด้วยพหุนามเศษส่วนและแพ็คเกจเสี่ยงการแข่งขันที่ฉันต้องการความช่วยเหลือ


ปัญหา

ฉันไม่สามารถหาวิธีง่าย ๆ ในการวิเคราะห์ค่าสัมประสิทธิ์เวลาได้ใน R ฉันต้องการให้สามารถใช้สัมประสิทธิ์ตัวแปรของฉันและทำมันเป็นค่าสัมประสิทธิ์ขึ้นอยู่กับเวลา (ไม่ใช่ตัวแปร) แล้วพล็อตการเปลี่ยนแปลงกับเวลา:

βม.Y_โวลต์aRผมaล.อี=β0+β1* * * *เสื้อ+β2* * * *เสื้อ2...

การแก้ปัญหาที่เป็นไปได้

1) การแยกชุดข้อมูล

ฉันได้ดูตัวอย่างนี้ (Se ส่วนที่ 2 ของเซสชันแล็บ) แต่การสร้างชุดข้อมูลแยกต่างหากดูเหมือนซับซ้อนซับซ้อนคำนวณค่าใช้จ่ายและไม่ง่ายมาก ...

2) Reduced Rank models - แพ็คเกจ coxvc

แพคเกจ coxvcให้เป็นวิธีที่สง่างามของการจัดการกับปัญหา - นี่เป็นคู่มือ ปัญหาคือผู้เขียนไม่ได้พัฒนาแพ็คเกจ (เวอร์ชั่นล่าสุดคือตั้งแต่วันที่ 23/23/2007) หลังจากการสนทนาทางอีเมลบางครั้งฉันได้รับแพ็คเกจเพื่อใช้งาน แต่การทำงานหนึ่งครั้งใช้เวลา 5 ชั่วโมงในชุดข้อมูลของฉัน (140 000 รายการ) และให้การประมาณการที่มากในตอนท้ายของช่วงเวลา คุณสามารถค้นหาแพ็คเกจที่อัปเดตได้ที่นี่ - ฉันเพิ่งปรับปรุงฟังก์ชั่นการแปลงเป็นส่วนใหญ่

อาจเป็นเพียงคำถามของการปรับเปลี่ยน แต่เนื่องจากซอฟต์แวร์ไม่สามารถให้ช่วงความมั่นใจได้อย่างง่ายดายและกระบวนการนี้ใช้เวลานานดังนั้นตอนนี้ฉันจึงดูโซลูชันอื่น ๆ

3) แพ็คเกจ timereg

แพ็คเกจ timereg ที่น่าประทับใจยังแก้ปัญหาได้ แต่ฉันไม่แน่ใจว่าจะใช้งานอย่างไรและมันก็ไม่ได้ช่วยให้ฉันวางแผนได้อย่างราบรื่น

4) โมเดลพหุนาม Fractional Time (FPT)

ฉันพบวิทยานิพนธ์ปริญญานิพนธ์ที่ยอดเยี่ยมของ Anika Buchholz เกี่ยวกับ"การประเมินผลกระทบระยะยาวที่แตกต่างกันของการรักษาและปัจจัยการพยากรณ์โรค"ซึ่งเป็นงานที่ยอดเยี่ยมซึ่งครอบคลุมโมเดลที่แตกต่างกัน เธอสรุปว่าFPT ที่เสนอของ Sauerbrei et alดูเหมือนจะเหมาะสมที่สุดสำหรับค่าสัมประสิทธิ์ตามเวลา:

FPT นั้นดีมากในการตรวจจับเอฟเฟกต์ที่หลากหลายตามเวลาในขณะที่วิธีการลดอันดับนั้นจะส่งผลให้ตัวแบบซับซ้อนเกินไปเนื่องจากไม่ได้รวมการเลือกเอฟเฟกต์ที่เปลี่ยนแปลงตามเวลา

การวิจัยดูเหมือนจะสมบูรณ์มาก แต่ฉันก็เอื้อมไม่ออกเลย ฉันยังสงสัยเล็กน้อยเนื่องจากเธอทำงานกับ Sauerbrei ดูเหมือนว่าจะฟังดูดีและฉันคิดว่าการวิเคราะห์สามารถทำได้ด้วยแพ็คเกจ mfpแต่ฉันก็ไม่แน่ใจ

5) แพคเกจ cmprsk

ฉันได้คิดถึงการวิเคราะห์ความเสี่ยงของคู่แข่ง แต่การคำนวณนั้นใช้เวลานานดังนั้นฉันจึงเปลี่ยนมาใช้วิธีการถดถอยแบบค็อกซ์เป็นประจำ CRRมีตัวเลือกสำหรับการ thoug เวลาตัวแปรขึ้นอยู่นี้:

....
cov2        matrix of covariates that will be multiplied 
            by functions of time; if used, often these 
            covariates would also appear in cov1 to give 
            a prop hazards effect plus a time interaction
....

มีตัวอย่างกำลังสอง แต่ฉันไม่ได้ค่อนข้างตามเวลาที่ปรากฏจริงและฉันไม่แน่ใจว่าวิธีการแสดง ฉันได้ดูไฟล์ test.R แล้ว แต่ตัวอย่างก็มีเหมือนกัน ...

รหัสตัวอย่างของฉัน

นี่คือตัวอย่างที่ฉันใช้ทดสอบความเป็นไปได้ที่แตกต่างกัน

library("survival")
library("timereg")
data(sTRACE)

# Basic cox regression    
surv <- with(sTRACE, Surv(time/365,status==9))
fit1 <- coxph(surv~age+sex+diabetes+chf+vf, data=sTRACE)
check <- cox.zph(fit1)
print(check)
plot(check, resid=F)
# vf seems to be the most time varying

######################################
# Do the analysis with the code from #
# the example that I've found        #
######################################

# Split the dataset according to the splitSurv() from prof. Wesley O. Johnson
# http://anson.ucdavis.edu/~johnson/st222/lab8/splitSurv.ssc
new_split_dataset = splitSuv(sTRACE$time/365, sTRACE$status==9, sTRACE[, grep("(age|sex|diabetes|chf|vf)", names(sTRACE))])

surv2 <- with(new_split_dataset, Surv(start, stop, event))
fit2 <- coxph(surv2~age+sex+diabetes+chf+I(pspline(stop)*vf), data=new_split_dataset)
print(fit2)

######################################
# Do the analysis by just straifying #
######################################
fit3 <- coxph(surv~age+sex+diabetes+chf+strata(vf), data=sTRACE)
print(fit3)

# High computational cost!
# The price for 259 events
sum((sTRACE$status==9)*1)
# ~240 times larger dataset!
NROW(new_split_dataset)/NROW(sTRACE)

########################################
# Do the analysis with the coxvc and   #
# the timecox from the timereg library #
########################################
Ft_1 <- cbind(rep(1,nrow(sTRACE)),bs(sTRACE$time/365,df=3))
fit_coxvc1 <- coxvc(surv~vf+sex, Ft_1, rank=2, data=sTRACE)

fit_coxvc2 <- coxvc(surv~vf+sex, Ft_1, rank=1, data=sTRACE)

Ft_3 <- cbind(rep(1,nrow(sTRACE)),bs(sTRACE$time/365,df=5))
fit_coxvc3 <- coxvc(surv~vf+sex, Ft_3, rank=2, data=sTRACE)

layout(matrix(1:3, ncol=1))
my_plotcoxvc <- function(fit, fun="effects"){
    plotcoxvc(fit,fun=fun,xlab='time in years', ylim=c(-1,1), legend_x=.010)
    abline(0,0, lty=2, col=rgb(.5,.5,.5,.5))
    title(paste("B-spline =", NCOL(fit$Ftime)-1, "df and rank =", fit$rank))
}
my_plotcoxvc(fit_coxvc1)
my_plotcoxvc(fit_coxvc2)
my_plotcoxvc(fit_coxvc3)

# Next group
my_plotcoxvc(fit_coxvc1)

fit_timecox1<-timecox(surv~sex + vf, data=sTRACE)
plot(fit_timecox1, xlab="time in years", specific.comps=c(2,3))

โค้ดส่งผลให้กราฟเหล่านี้: เปรียบเทียบการตั้งค่าที่แตกต่างกันสำหรับ coxvcและของ coxvc และพล็อตtimecox ฉันเดาว่าผลลัพธ์จะใช้ได้ แต่ฉันไม่คิดว่าฉันจะสามารถอธิบายกราฟ timecox ได้ - ดูเหมือนว่าจะซับซ้อน ...

คำถามของฉัน (ปัจจุบัน)

  • ฉันจะทำการวิเคราะห์ FPT ใน R ได้อย่างไร
  • ฉันจะใช้เวลา covariate เป็น cmprsk ได้อย่างไร
  • ฉันจะพล็อตผลลัพธ์ได้อย่างไร (ควรมีช่วงความมั่นใจเป็นพิเศษ)

3
ตัวอย่างในลิงค์นี้เกี่ยวกับตัวแปรแปรผันตามเวลาไม่ใช่ค่าสัมประสิทธิ์แปรผันตามเวลา สิ่งเหล่านี้แตกต่างกันมากเกินไป จะได้รับเวลาที่แตกต่างกันพารามิเตอร์ในแบบที่คุณอธิบายถึงการใช้การโต้ตอบเช่นแทนของรูปแบบพอดีรูปแบบT ใน R สูตรจะมีลักษณะและ(อาจเป็นไปได้ที่จะเขียนสำหรับสุดท้าย) Y=xβม.YY=xβ0+xเสื้อβ1+xเสื้อ2β2y~xy~x*(t+t^2)-ty~x+x:t+x:t^2
mpiktas

ฉันคิดว่าส่วนที่สอง: "2. ตัวแบบโควาริเอตขึ้นอยู่กับเวลาที่กำหนดเพื่อตรวจสอบข้อสมมติฐาน PH" จะเป็นส่วนที่จัดการกับคำถามของฉัน ฉันหวังว่าจะทำบางสิ่งบางอย่างของสูตรที่คุณอธิบาย แต่เมื่อฉันลองฉันอาจมีข้อผิดพลาดหรือตัวแปรเวลาแยกกัน ... ฉันได้ค่า p ต่ำในช่วงเวลาที่ :-D
Max Gordon

@ max-gordon ตัวแปรตอบสนองของคุณเป็นปริมาณหรือเวลาที่ผ่านไปจนกว่าจะเกิดขึ้นได้หรือไม่ เนื่องจากวิธีการส่วนใหญ่ที่คุณอ้างถึงนั้นใช้สำหรับข้อมูลเวลาเป็นเหตุการณ์โดยเฉพาะ
f1r3br4nd

@ f1r3br4nd: มันเป็นปริมาณ (อายุในการศึกษาของฉัน) ที่อันตรายไม่ได้เป็นสัดส่วนนั่นคือมันแตกต่างกันไปตามเวลาในรูปแบบเวลาต่อเหตุการณ์ของฉัน ในที่สุดฉันตัดสินใจที่จะแบ่งออกเป็นสองช่วงเวลาที่แตกต่างกันเพราะฉันไม่ได้ตื่นเต้นกับการทำกราฟ 3 มิติ - ที่จะไม่เคยผ่านการตรวจสอบ ...
Max Gordon

มีความแตกต่างระหว่างตัวทำนายที่ขึ้นกับเวลา / การเปลี่ยนแปลงที่แตกต่างกันและการโต้ตอบกับเวลา ตัวแปรส่วนใหญ่ขึ้นอยู่กับเวลา (เพศเป็นข้อยกเว้น) หากคุณมีหนึ่งการสังเกตต่อคนคุณจะมีโอกาสน้อยมากหรือไม่มีเลยที่จะทำการวิเคราะห์ตามเวลา / เปลี่ยนแปลง วิธีการของแอนเดอร์สัน - กิลล์เป็นวิธีที่ใช้บ่อยที่สุดสำหรับการวิเคราะห์การรอดชีวิตแบบพึ่งพาอาศัยเวลา ข้อดีของวิธีการที่ขึ้นอยู่กับเวลาคือค่าระหว่างการติดตามอาจเป็นการทำนายประสบการณ์การเอาชีวิตรอดมากกว่าค่าพื้นฐาน สถานการณ์ที่สองตัวทำนายเวลาแบบโต้ตอบเวลาเป็นเพียงการทดสอบสมมติฐาน PH
Adam Robinsson

คำตอบ:


8

@mpiktas เข้ามาใกล้ในการเสนอรูปแบบที่เป็นไปได้ แต่ในระยะที่ความต้องการที่จะใช้สำหรับการกำลังสองในเวลาที่ t = I(t^2))จะเป็น นี่เป็นเช่นนั้นเพราะใน R การตีความสูตรของ "^" จะสร้างการโต้ตอบและไม่ทำการยกกำลังดังนั้นการโต้ตอบของ "t" กับ "t" จึงเป็นเพียงแค่ "t" (สิ่งนี้ไม่ควรถูกย้ายไปยัง SO ด้วยแท็ก [r] ใช่ไหม)

สำหรับทางเลือกในกระบวนการนี้ซึ่งดูเหมือนว่าฉันค่อนข้างไม่แน่ใจสำหรับวัตถุประสงค์การอนุมานและสิ่งที่เหมาะสมกับความสนใจของคุณในการใช้ฟังก์ชั่นการสนับสนุนในแพ็คเกจ rms / Hmisc ของ Harrell ให้ดู "กลยุทธ์การสร้างแบบจำลองการถดถอย" ของ Harrell เขากล่าวถึง (แต่เมื่อผ่านแม้ว่าเขาจะอ้างถึงเอกสารของเขาเอง) การสร้างเส้นโค้งที่เหมาะกับขนาดเวลาเพื่อจำลองอันตรายที่มีรูปร่างคล้ายอ่างอาบน้ำ บทของเขาเกี่ยวกับแบบจำลองการเอาชีวิตรอดแบบ Parametric อธิบายถึงเทคนิคการวางแผนต่าง ๆ สำหรับการตรวจสอบสมมติฐานความเป็นอันตรายตามสัดส่วน

แก้ไข: ตัวเลือกเพิ่มเติมคือใช้coxphพารามิเตอร์ 'tt' ที่อธิบายว่าเป็น "รายการตัวเลือกของฟังก์ชั่นเปลี่ยนเวลา"


ฉันยอมรับว่าสิ่งนี้น่าจะถูกย้ายไปที่แท็ก SO [r]
Zach

+1 สำหรับคำตอบของคุณฉันไม่รู้ว่านี่จะเป็นการตอบยาก ดูเหมือนว่าเป็นปัญหาที่พบบ่อยบางทีคำถามนี้อาจเป็นคำถามของการเข้ารหัสมากกว่าและคุณอาจพูดถูกว่าเป็นตัวเลือกที่ดีกว่า ฉันลองสูตรของคุณดูเหมือนว่า vf + I (vf log (เวลา)) มีขนาดพอดีฉันลองแค่ vf time และ vf * time ^ 2 แต่บันทึกให้ค่า p-value ต่ำสุด ฉันพยายามเรียกใช้ด้วยฟังก์ชัน cph () เพื่อรับ AIC แต่มีข้อผิดพลาด :( คุณมีความคิดเกี่ยวกับวิธีการทำพล็อตในการประมาณหรือไม่?
Max Gordon

ฉันคิดว่าcheck <- cox.zph(fit1); print(check); plot(check, resid=F)ในการตั้งค่าของคุณให้แปลงข้อมูลของเวลา "ผล" คุณหมายถึง cph () ซึ่งมาจากแพ็คเกจ rms หรือ coxph จากการอยู่รอด
DWIN

ใช่ส่วนที่เหลือของ Schoenfeld ให้ความคิดที่ดีเกี่ยวกับความแปรปรวนของเวลา แต่ฉันคิดว่าผู้คนอาจเข้าใจยาก พล็อตให้ที่ฉันเข้าใจรูปแบบที่เหลือไม่ได้อธิบายโดยแบบจำลองของฉัน ฉันต้องการพล็อตที่ฉันมีเอฟเฟ็กต์ตัวแปรทั้งหมดในแกน y และเวลาบนแกน x ฉันเชื่อว่านี่จะง่ายต่อการตีความเนื่องจากคุณไม่ต้องดูทั้งตารางและพล็อต เพื่อให้ได้อันตรายตามเวลาที่กำหนด ... ใช่ฉันหมายถึง cph () และไม่ใช่ coxph () เนื่องจากไม่สามารถใช้งานได้กับ AIC ()
Max Gordon

ฉันยังสับสนเล็กน้อยว่าทำไมฉันจึงพบวิธีการที่ซับซ้อนทั้งหมดที่อธิบายไว้ในคำถามของฉันในขณะที่ฉัน (ตัวแปร * เวลา) ดูเหมือนตรงไปตรงมาและใช้งานง่าย - ในฐานะนักสถิติที่ฉันคิด - สิ่งที่ฉันพลาด ?
Max Gordon

5

ฉันได้เปลี่ยนคำตอบสำหรับคำถามนี้เนื่องจากคำตอบของ @ DWin หรือ @ Zach ไม่ได้ตอบคำถามทั้งหมดเกี่ยวกับวิธีการสร้างแบบจำลองสัมประสิทธิ์การเปลี่ยนแปลงเวลา ฉันเพิ่งเขียนโพสต์เกี่ยวกับเรื่องนี้ นี่คือส่วนสำคัญของมัน

ชั่วโมง(เสื้อ)

ชั่วโมง(เสื้อ)=(เสื้อ)S(เสื้อ)

(เสื้อ)S(เสื้อ)0

เสื้อผมม.อี0S(เสื้อ)

เมื่อปล่อยให้อาสาสมัครเข้ามาที่จุดเวลาอื่น ๆ ที่เราต้องเปลี่ยนSurvจากการSurv(time, status) Surv(start_time, end_time, status)แม้ว่าend_timeจะมีความสัมพันธ์อย่างมากกับผลลัพธ์ แต่start_timeขณะนี้มีให้บริการในรูปแบบของการโต้ตอบ (เช่นเดียวกับคำแนะนำดั้งเดิม) ในการตั้งค่าปกติstart_timeคือ 0 ยกเว้นบางตัวอย่างที่ปรากฏในภายหลัง แต่เราแยกการสังเกตแต่ละครั้งเป็นหลายช่วงเวลาเรามีเวลาเริ่มต้นที่มากมายซึ่งไม่ใช่ศูนย์ ความแตกต่างเพียงอย่างเดียวคือการสังเกตแต่ละครั้งเกิดขึ้นหลายครั้งที่การสังเกตทั้งหมด แต่การสังเกตครั้งสุดท้ายมีตัวเลือกของผลลัพธ์ที่ไม่ถูกเซ็นเซอร์

แบ่งเวลาในการปฏิบัติ

ฉันเพิ่งเผยแพร่บน CRAN แพ็คเกจGregซึ่งทำให้การแบ่งเวลาเป็นเรื่องง่าย ก่อนอื่นเราเริ่มด้วยการสังเกตทางทฤษฎี:

library(Greg)
test_data <- data.frame(
  id = 1:4,
  time = c(4, 3.5, 1, 5),
  event = c("censored", "dead", "alive", "dead"),
  age = c(62.2, 55.3, 73.7, 46.3),
  date = as.Date(
    c("2003-01-01", 
      "2010-04-01", 
      "2013-09-20",
      "2002-02-23"))
)

เราสามารถแสดงกราฟนี้ด้วย * เป็นตัวบ่งชี้เหตุการณ์:

ป้อนคำอธิบายรูปภาพที่นี่

ถ้าเราใช้timeSplitterดังต่อไปนี้:

library(dplyr)
split_data <- 
  test_data %>% 
  select(id, event, time, age, date) %>% 
  timeSplitter(by = 2, # The time that we want to split by
               event_var = "event",
               time_var = "time",
               event_start_status = "alive",
               time_related_vars = c("age", "date"))

เราได้รับดังต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ในขณะที่คุณสามารถดูแต่ละวัตถุถูกแบ่งออกเป็นหลายเหตุการณ์ที่ช่วงเวลาล่าสุดมีสถานะเหตุการณ์จริง สิ่งนี้ทำให้เราสามารถสร้างแบบจำลองที่มี:เงื่อนไขการโต้ตอบง่าย ๆ(อย่าใช้ส่วน*ขยายนี้time + var + time:varและเราไม่สนใจเวลาต่อไป) ไม่จำเป็นต้องมีการใช้ไม่เป็นI()ฟังก์ชั่น rms::contrastแต่ถ้าคุณต้องการตรวจสอบไม่เป็นเชิงเส้นด้วยเวลาผมมักจะสร้างตัวแปรเวลาปฏิสัมพันธ์ที่แยกต่างหากที่ฉันจะเพิ่มอิสระให้แล้วแสดงโดยใช้ อย่างไรก็ตามตอนนี้การเรียกการถดถอยของคุณควรมีลักษณะเช่นนี้:

coxp(Surv(start_time, end_time, event) ~ var1 + var2 + var2:time, 
     data = time_split_data)

การใช้ttฟังก์ชั่นแพคเกจการอยู่รอด

นอกจากนี้ยังมีวิธีการสร้างแบบจำลองสัมประสิทธิ์เวลาขึ้นอยู่กับแพคเกจการเอาตัวรอดโดยตรงโดยใช้ttฟังก์ชัน ศ. Therneau ให้การแนะนำอย่างละเอียดกับเรื่องในของเขาบทความ น่าเสียดายที่ในชุดข้อมูลขนาดใหญ่สิ่งนี้ทำได้ยากเนื่องจากข้อ จำกัด ของหน่วยความจำ ดูเหมือนว่าttฟังก์ชั่นจะแบ่งเวลาออกเป็นชิ้นเล็ก ๆ ที่สร้างขึ้นในกระบวนการเป็นเมทริกซ์ขนาดใหญ่


2

คุณสามารถใช้ฟังก์ชั่นApply.rollingในPerformanceAnalyticsเพื่อเรียกใช้การถดถอยเชิงเส้นผ่านหน้าต่างกลิ้งซึ่งจะช่วยให้ค่าสัมประสิทธิ์ของคุณแตกต่างกันไปตามช่วงเวลา

ตัวอย่างเช่น:

library(PerformanceAnalytics)
library(quantmod)
getSymbols(c('AAPL','SPY'), from='01-01-1900')
chart.RollingRegression(Cl(AAPL),Cl(SPY), width=252, attribute='Beta')
#Note: Alpha=y-intercept, Beta=regression coeffient

ใช้ได้กับฟังก์ชั่นอื่นเช่นกัน


ขอบคุณสำหรับคำตอบของคุณฉันเดาว่าหน้าต่างเวลาที่เคลื่อนไหวน่าจะใช้ได้เช่นเดียวกับแนวทางของฉัน ฉันไม่สามารถเรียกใช้ตัวอย่างของคุณได้คุณช่วยยกตัวอย่างจากตัวอย่าง sTRACE ของฉันเพื่อให้ฉันรู้วิธีนำไปใช้จริงหรือไม่?
Max Gordon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.