Hệ số phụ thuộc thời gian trong R - làm thế nào để làm điều đó?


17

Cập nhật : Xin lỗi vì một bản cập nhật khác nhưng tôi đã tìm thấy một số giải pháp khả thi với đa thức phân số và gói rủi ro cạnh tranh mà tôi cần một số trợ giúp.


Vấn đề

Tôi không thể tìm thấy một cách dễ dàng để thực hiện phân tích hệ số phụ thuộc thời gian trong R. Tôi muốn có thể lấy hệ số biến của mình và thực hiện nó thành một hệ số phụ thuộc thời gian (không phải biến) và sau đó vẽ biểu đồ biến đổi theo thời gian:

βmy_vmộtrTôimộtbtôie= =β0+β1*t+β2*t2...

Phương pháp khả thi

1) Chia dữ liệu

Tôi đã xem ví dụ này (Se phần 2 của phiên phòng thí nghiệm) nhưng việc tạo một bộ dữ liệu riêng biệt có vẻ phức tạp, tốn kém về mặt tính toán và không trực quan lắm ...

2) Các mô hình xếp hạng giảm - Gói coxvc

Các gói coxvc cung cấp một cách thanh lịch để đối phó với vấn đề này - đây là một nhãn hiệu . Vấn đề là tác giả không còn phát triển gói (phiên bản mới nhất là từ ngày 23/05/2007), sau một số cuộc trò chuyện email tôi đã nhận được gói để hoạt động nhưng một lần chạy mất 5 giờ trên tập dữ liệu của tôi (140 000 mục) và đưa ra ước tính cực đoan vào cuối kỳ. Bạn có thể tìm thấy một gói cập nhật nhẹ ở đây - Tôi hầu như chỉ cập nhật chức năng cốt truyện.

Nó có thể chỉ là một câu hỏi về tinh chỉnh nhưng vì phần mềm không dễ dàng cung cấp khoảng tin cậy và quá trình này rất tốn thời gian nên tôi đang tìm kiếm các giải pháp khác ngay bây giờ.

3) Gói timereg

Gói timereg ấn tượng cũng giải quyết được vấn đề nhưng tôi không chắc chắn về cách sử dụng nó và nó không mang lại cho tôi một cốt truyện mượt mà.

4) Mô hình thời gian đa thức phân số (FPT)

Tôi tìm thấy luận án xuất sắc của Anika Buchholz về "Đánh giá thời gian khác nhau về tác dụng dài hạn của các phương pháp trị liệu và các yếu tố tiên lượng" , một công việc tuyệt vời bao gồm các mô hình khác nhau. Bà kết luận rằng đề xuất FPT của Sauerbrei et al có vẻ phù hợp nhất với các hệ số phụ thuộc vào thời gian:

FPT rất giỏi trong việc phát hiện các hiệu ứng thay đổi theo thời gian, trong khi phương pháp Xếp hạng giảm dẫn đến các mô hình quá phức tạp, vì nó không bao gồm lựa chọn các hiệu ứng thay đổi theo thời gian.

Nghiên cứu có vẻ rất đầy đủ nhưng nó hơi ngoài tầm với của tôi. Tôi cũng có một chút thắc mắc kể từ khi cô ấy làm việc với Sauerbrei. Có vẻ như âm thanh và tôi đoán phân tích có thể được thực hiện với gói mfp nhưng tôi không chắc làm thế nào.

5) Gói cmprsk

Tôi đã nghĩ đến việc thực hiện phân tích rủi ro cạnh tranh của mình nhưng các tính toán đã tốn thời gian nên tôi chuyển sang hồi quy cox thông thường. Các crr có một tùy chọn cho các hiệp phương thức phụ thuộc thời gian:

....
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
....

Có một ví dụ bậc hai nhưng tôi không hoàn toàn theo dõi thời gian thực sự xuất hiện và tôi không chắc chắn về cách hiển thị nó. Tôi cũng đã xem tệp test.R nhưng ví dụ về cơ bản là giống nhau ...

Mã ví dụ của tôi

Đây là một ví dụ mà tôi sử dụng để kiểm tra các khả năng khác nhau

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))

Mã kết quả trong các biểu đồ này: So sánh các cài đặt khác nhau cho coxvc và của coxvc và các ô thời gian. Tôi đoán kết quả là ổn nhưng tôi không nghĩ rằng tôi có thể giải thích biểu đồ timecox - nó có vẻ phức tạp ...

Câu hỏi của tôi (hiện tại)

  • Làm cách nào để phân tích FPT trong R?
  • Làm cách nào để sử dụng đồng biến thời gian trong cmprsk?
  • Làm thế nào để tôi vẽ kết quả (tốt nhất là với khoảng tin cậy)?

3
y= =xβmyy= =xβ0+xtβ1+xt2β2y~xy~x*(t+t^2)-ty~x+x:t+x:t^2

Tôi nghĩ phần thứ hai: "2. Các đồng biến phụ thuộc thời gian xác định mô hình để kiểm tra giả định PH" sẽ là phần giải quyết câu hỏi của tôi. Tôi đã hy vọng làm một cái gì đó theo công thức mà bạn mô tả nhưng khi tôi thử nó tôi đã gặp lỗi hoặc biến thời gian riêng biệt ... Tôi đã nhận được giá trị p thấp cho thời gian mặc dù :-D
Max Gordon

@ max-gordon, phản ứng của bạn có phải là một đại lượng hay thời gian trôi qua cho đến khi xảy ra chẵn? Bởi vì hầu hết các phương pháp bạn trích dẫn là dành riêng cho dữ liệu theo thời gian.
F1r3br4 và

@ f1r3br4nd: Đó là một đại lượng (Tuổi trong nghiên cứu của tôi) trong đó mức độ nguy hiểm không theo tỷ lệ, tức là nó thay đổi theo thời gian trong mô hình theo sự kiện của tôi. Cuối cùng, tôi quyết định chia thành hai khung thời gian khác nhau vì tôi không cảm thấy hồi hộp khi thực hiện đồ thị 3 chiều - điều đó sẽ không bao giờ vượt qua các nhà phê bình ...
Max Gordon

Có sự khác biệt giữa các yếu tố dự đoán / thay đổi thời gian và tương tác thời gian. Hầu hết các biến là phụ thuộc thời gian (tình dục là một ngoại lệ). Nếu bạn có một quan sát cho mỗi người, thì bạn sẽ có ít hoặc không có cơ hội thực hiện phân tích phụ thuộc thời gian / thay đổi. Phương pháp của Anderson-Gill được sử dụng thường xuyên nhất để phân tích tỷ lệ sống phụ thuộc vào thời gian. Ưu điểm của phương pháp phụ thuộc thời gian là các giá trị trong quá trình theo dõi có thể dự đoán nhiều hơn về trải nghiệm sinh tồn so với giá trị cơ bản. Tình huống thứ hai, các yếu tố dự đoán tương tác thời gian chỉ đơn giản là các thử nghiệm về giả định PH.
Adam Robinsson

Câu trả lời:


8

@mpiktas đã tiến gần đến việc đưa ra một mô hình khả thi, tuy nhiên thuật ngữ cần được sử dụng cho phương trình bậc hai trong thời gian = t sẽ là I(t^2)). Điều này là như vậy bởi vì trong R, việc giải thích công thức của "^" tạo ra các tương tác và không thực hiện lũy thừa, do đó, tương tác của "t" với "t" chỉ là "t". (Không nên di chuyển sang SO bằng thẻ [r]?)

Đối với các lựa chọn thay thế cho quy trình này, có vẻ như tôi hơi mơ hồ cho các mục đích suy luận và một trong số đó có thể phù hợp với sở thích của bạn trong việc sử dụng các chức năng hỗ trợ trong các gói rms / Hmisc của Harrell, xem "Chiến lược mô hình hồi quy" của Mitchell. Anh ta đề cập (nhưng chỉ thông qua mặc dù anh ta đã trích dẫn một số giấy tờ của riêng mình) xây dựng spline phù hợp với quy mô thời gian để mô hình các mối nguy hình bồn tắm. Chương của ông về các mô hình sống sót tham số mô tả một loạt các kỹ thuật âm mưu để kiểm tra các giả định về mối nguy theo tỷ lệ và để kiểm tra tính tuyến tính của các tác động nguy hiểm log ước tính theo thang thời gian.

Chỉnh sửa: Một tùy chọn bổ sung là sử dụng coxphtham số 's' tt 'được mô tả dưới dạng "danh sách tùy chọn các hàm biến đổi thời gian".


Tôi đồng ý rằng điều này có lẽ nên được chuyển sang thẻ SO [r].
Zach

+1 cho câu trả lời của bạn, tôi không biết rằng điều này sẽ rất khó trả lời. Có vẻ như là một vấn đề phổ biến, có lẽ câu hỏi liên quan đến mã hóa nhiều hơn và bạn có thể đúng về việc SO là một lựa chọn tốt hơn. Tôi đã thử công thức của bạn, có vẻ như vf + I (vf log (time)) rất phù hợp, tôi đã thử chỉ vf time và vf * time ^ 2 nhưng nhật ký được đưa ra bởi giá trị p thấp nhất. Tôi đã thử chạy nó với hàm cph () để lấy AIC nhưng nó đã báo lỗi :( Bạn có biết làm thế nào để thực hiện một âm mưu trên ước tính không?
Max Gordon

Tôi nghĩ rằng check <- cox.zph(fit1); print(check); plot(check, resid=F)như trong thiết lập của bạn đã đưa ra các âm mưu thông tin về "hiệu ứng" thời gian. Ý của bạn là cph () từ gói rms hay coxph từ sự sống sót?
DWin

Vâng, phần dư Schoenfeld cho một ý tưởng hay về sự biến đổi thời gian nhưng tôi nghĩ mọi người có thể khó hiểu về nó. Cốt truyện đưa ra khi tôi hiểu nó là biến thể còn lại không được giải thích bởi mô hình của tôi. Tôi muốn mặc dù một âm mưu trong đó tôi có hiệu ứng biến hoàn toàn trên trục y và thời gian trên trục x, tôi tin rằng điều này sẽ dễ diễn giải hơn vì bạn không phải nhìn vào cả bảng và âm mưu để có được mối nguy hiểm tại một thời điểm cụ thể ... Vâng, ý tôi là cph () chứ không phải coxph () vì nó không hoạt động với AIC ()
Max Gordon

Tôi cũng hơi bối rối về lý do tại sao tôi tìm thấy tất cả các phương pháp phức tạp được mô tả trong câu hỏi của mình trong khi điều này tôi (biến * thời gian) có vẻ rất thẳng về phía trước và trực quan - như một người không thống kê tôi đang nghĩ - tôi đã bỏ lỡ điều gì ?
Tối đa

5

Tôi đã thay đổi câu trả lời cho câu trả lời này vì cả câu trả lời của @ DWin hoặc @ Zach đều trả lời đầy đủ cách mô hình hóa các hệ số thay đổi theo thời gian. Gần đây tôi đã viết một bài về điều này. Đây là ý chính của nó.

Khái niệm cốt lõi trong mô hình hồi quy Coxh(t)

h(t)= =f(t)S(t)

f(t)S(t)0

tTôime0S(t)

Khi cho phép các đối tượng nhập vào các thời điểm khác, chúng ta phải thay đổi Survtừ Surv(time, status)thành Surv(start_time, end_time, status). Mặc dù end_timetương quan mạnh mẽ với kết quả, start_timehiện tại nó có sẵn như là một thuật ngữ tương tác (giống như được gợi ý trong các đề xuất ban đầu). Trong cài đặt thông thường, giá trị start_timelà 0 ngoại trừ một vài đối tượng xuất hiện muộn hơn nhưng chúng ta chia mỗi lần quan sát thành nhiều giai đoạn, chúng ta đột nhiên có nhiều thời gian bắt đầu khác không. Sự khác biệt duy nhất là mỗi quan sát xảy ra nhiều lần trong đó tất cả trừ lần quan sát cuối cùng có tùy chọn kết quả không kiểm duyệt.

Chia thời gian trong thực tế

Tôi vừa xuất bản trên CRAN gói Greg giúp việc phân chia thời gian này trở nên dễ dàng. Đầu tiên chúng ta bắt đầu với một số quan sát lý thuyết:

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"))
)

Chúng ta có thể hiển thị đồ họa này với * là một chỉ báo của sự kiện:

nhập mô tả hình ảnh ở đây

Nếu chúng ta áp dụng timeSplitternhư sau:

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"))

Chúng tôi nhận được như sau:

nhập mô tả hình ảnh ở đây

Như bạn có thể thấy mỗi đối tượng đã được chia thành nhiều sự kiện trong đó khoảng thời gian cuối cùng chứa trạng thái sự kiện thực tế. Điều này cho phép chúng tôi xây dựng các mô hình có :các điều khoản tương tác đơn giản (không sử dụng *khi điều này mở rộng time + var + time:varvà chúng tôi không quan tâm đến thời gian mỗi lần). Không có nhu cầu sử dụngI() hàm mặc dù nếu bạn muốn kiểm tra tính phi tuyến theo thời gian, tôi thường tạo một biến tương tác thời gian riêng biệt mà tôi thêm một spline vào và sau đó hiển thị bằng cách sử dụng rms::contrast. Dù sao, cuộc gọi hồi quy của bạn bây giờ sẽ trông như thế này:

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

Sử dụng ttchức năng của gói sinh tồn

Ngoài ra còn có một cách để mô hình hóa các hệ số phụ thuộc thời gian trực tiếp trong gói sinh tồn bằng cách sử dụng tthàm. Giáo sư Therneau cung cấp một giới thiệu kỹ lưỡng về chủ đề trong họa tiết của mình . Thật không may trong các bộ dữ liệu lớn, điều này khó thực hiện do giới hạn bộ nhớ. Có vẻ như tthàm chia thời gian thành các phần rất nhỏ tạo ra trong quá trình một ma trận khổng lồ.


2

Bạn có thể sử dụng chức năng application.rolling trong PerformanceAnalytics để chạy hồi quy tuyến tính thông qua cửa sổ cuộn, điều này sẽ cho phép các hệ số của bạn thay đổi theo thời gian.

Ví dụ:

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

Điều này hoạt động với các chức năng khác quá.


Cảm ơn câu trả lời của bạn, tôi đoán một cửa sổ thời gian chuyển động sẽ hoạt động tốt như các phương pháp của tôi. Mặc dù vậy, tôi không thể lấy ví dụ của bạn để chạy, bạn có thể vui lòng cho một ví dụ dựa trên ví dụ sTRACE của tôi để tôi biết chính xác cách triển khai không?
Tối đa Gordon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.