R'de zamana bağlı katsayılar - nasıl yapılır?


17

Güncelleme : Başka bir güncelleme için özür dilerim ama fraksiyonel polinomlar ve yardıma ihtiyacım olan rakip risk paketi ile bazı olası çözümler buldum.


Sorun

Zamana bağlı katsayı analizi R'de yapmanın kolay bir yolunu bulamıyorum. Değişkenlerimi katsayı almak ve zamana bağlı bir katsayıya (değişken değil) dönüştürmek ve zamana karşı varyasyon çizmek istiyorum:

βmy_vbirrbenbirble=β0+β1*t+β2*t2...

Muhtemel çözümler

1) Veri kümesini bölme

Bu örneğe baktım (laboratuvar oturumunun 2. bölümü) ama ayrı bir veri kümesinin oluşturulması karmaşık, hesaplama açısından maliyetli ve çok sezgisel değil ...

2) İndirgenmiş Rank modelleri - coxvc paketi

Coxvc paket sorunla ilgilenen zarif bir yol sağlar - burada var manuel . Sorun şu ki, yazar artık paketi geliştirmiyor (son sürüm 05/23/2007'den beri), bazı e-posta görüşmelerinden sonra paketi çalıştırdım ama bir çalışma veri kümemde 5 saat sürdü (140 000 girişler) ve dönem sonunda aşırı tahminler verir. Burada biraz güncellenmiş bir paket bulabilirsiniz - çoğunlukla arsa işlevini güncelledim.

Bu sadece bir ayarlama sorunu olabilir, ancak yazılım kolayca güven aralıkları sağlamadığından ve süreç çok zaman aldığından, şu anda diğer çözümlere bakıyorum.

3) Zaman paketi

Etkileyici timereg paketi de sorunu ele alıyor, ancak nasıl kullanılacağından emin değilim ve bana pürüzsüz bir arsa vermiyor.

4) Kesirli Polinom Zamanı (FPT) modeli

Anika Buchholz'un " Tedavilerin zamanla değişen uzun vadeli etkilerinin ve prognostik faktörlerin değerlendirilmesi" konusundaki mükemmel tezini farklı modelleri kapsayan mükemmel bir iş buldum . Sauerbrei ve arkadaşlarının önerdiği FPT'nin zamana bağlı katsayılar için en uygun olduğu sonucuna varıyor :

FPT, zamanla değişen etkileri tespit etmede çok iyidir, Azalan Sıralama yaklaşımı, zamanla değişen efektlerin seçimini içermediğinden çok karmaşık modellerle sonuçlanır.

Araştırma çok eksiksiz görünüyor ama benim için biraz ulaşılamıyor. Sauerbrei ile çalıştığı için biraz merak ediyorum. Gerçi sağlam görünüyor ve analiz mfp paketi ile yapılabilir ama nasıl emin değilim.

5) cmprsk paketi

Rakip risk analizimi yapmayı düşünüyorum ama hesaplamalar zaman alıcıydı, bu yüzden düzenli cox regresyonuna geçtim. Crr zamana bağımlı değişkenler için bir seçenek thoug vardır:

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

İkinci dereceden bir örnek var, ancak zamanın gerçekte nerede göründüğünü tam olarak takip etmiyorum ve nasıl gösterileceğinden emin değilim. Ayrıca test.R dosyasına baktım ama örnek temelde aynı ...

Örnek kodum

Farklı olasılıkları test etmek için kullandığım bir örnek

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

Kod şu grafiklerle sonuçlanır: coxvc ve coxvc ile timecox grafiklerinin farklı ayarlarının karşılaştırılması . Sanırım sonuçlar iyi ama timecox grafiğini açıklayabileceğimi sanmıyorum - karmaşık görünüyor ...

(Mevcut) sorularım

  • R'de FPT analizini nasıl yapabilirim?
  • Cmprsk'te zaman değişkenini nasıl kullanırım?
  • Sonucu nasıl çizerim (tercihen güven aralıklarıyla)?

3
Bağlantıdaki örnek, zamanla değişen katsayılarla değil, zamanla değişen değişkenlerle ilgilidir. Bunlar çok farklı şeyler. Tarif ettiğiniz şekilde zamanla değişen parametreleri elde etmek için etkileşimleri kullanın, yani modeli yerine, y = x β 0 + x t β 1 + x t 2 β 2 modelini takın . R'de formüller benzeyecektir ve ( sonuncusu için de yazılabilir ). y=xβmyy=xβ0+xtβ1+xt2β2y~xy~x*(t+t^2)-ty~x+x:t+x:t^2
mpiktas

İkinci kısmı düşündüm: "2. PH Varsayımını Kontrol Etmek İçin Model Deterministik Zamana Bağlı Değişkenler" sorumla ilgili kısım olurdu. Açıkladığınız formülden bir şey yapmayı umuyordum ama denediğimde ya bir hata ya da ayrı bir zaman değişkeni aldım ... ama zaman için düşük bir p değeri aldım:
Max Gordon

@ max-gordon, yanıt değişkeniniz bir miktar mı, yoksa bir çift gerçekleşene kadar geçen süre mi? Çünkü alıntıladığınız yöntemlerin çoğu, özellikle olay zamanı verileri içindir.
f1r3br4nd

@ f1r3br4nd: Tehlikenin orantılı olmadığı bir miktardır (çalışmamdaki Yaş), yani olay zamanı modelimde zamanla değişir. Sonunda, 3 boyutlu bir grafik yaparak heyecan duymadığım için iki farklı zaman dilimine ayrılmaya karar verdim - bu hakemleri asla geçemezdi ...
Max Gordon

Zamana bağlı / değişken öngörücüler ile zaman etkileşimi arasında bir fark vardır. Değişkenlerin çoğu zamana bağımlıdır (cinsiyet bir istisnadır). Kişi başına bir gözleminiz varsa, zamana bağlı / değişken analiz yapma şansınız çok az olacaktır veya hiç şansınız olmayacaktır. Anderson-Gill'in yöntemi, zamana bağlı sağkalım analizi için en sık kullanılan yöntemdir. Zamana bağlı yöntemlerin avantajı, takip sırasındaki değerlerin yaşam deneyiminin başlangıç ​​değerlerinden daha belirleyici olabilmesidir. İkinci durum, zamanla etkileşen yordayıcılar basitçe PH varsayımının testleridir.
Adam Robinsson

Yanıtlar:


8

@mpiktas uygulanabilir bir model sunarken yaklaştı, ancak zaman içinde ikinci dereceden için kullanılması gereken terim = t olurdu I(t^2)). Çünkü R'de "^" formülünün yorumlanması etkileşimler yaratır ve üs alma gerçekleştirmez, bu nedenle "t" ile "t" arasındaki etkileşim sadece "t" olur. (Bu [r] etiketi ile SO'ya taşınmamalı mı?)

Bana çıkarım amaçlı biraz şüpheli görünen ve muhtemelen Harrell'in rms / Hmisc paketlerinde destekleyici işlevleri kullanma ilginizi çeken bu sürece alternatifler için bkz. Harrell'in "Regresyon Modelleme Stratejileri". Küvet şeklindeki tehlikeleri modellemek için zaman ölçeğine uygun spline oluşturmaktan (ancak sadece kendi kağıtlarından bazılarını alıntılamasına rağmen geçerken) bahseder. Parametrik sağkalım modelleri hakkındaki bölümü, orantılı tehlike varsayımlarını kontrol etmek ve zaman ölçeğinde tahmini log-tehlike etkilerinin doğrusallığını incelemek için çeşitli çizim tekniklerini açıklamaktadır.

Düzenleme: Ek bir seçenek coxph"isteğe bağlı zaman dönüştürme işlevleri listesi" olarak tanımlanan 's' tt 'parametresini kullanmaktır .


Bunun muhtemelen SO [r] etiketine taşınması gerektiğini kabul ediyorum.
Zach

Cevabınız için +1, bunun yanıtlamanın çok zor olacağını bilmiyordum. Bu yaygın bir sorun gibi görünüyor, belki de soru daha çok bir kodlama meselesidir ve SO'nun daha iyi bir seçim olması konusunda haklı olabilirsiniz. Formülünüzü denedim, vf + I (vf log (zaman)) mükemmel bir uyum sergiliyor, sadece vf time ve vf * time ^ 2'yi denedim, ancak günlük ücretle en düşük p değerini verdi. Ben AIC almak için cph () fonksiyonu ile çalıştırmak için çalıştı ama bir hata verdi :( Tahmin üzerine bir arsa yapmak nasıl bir fikrin var mı?
Max Gordon

Ben check <- cox.zph(fit1); print(check); plot(check, resid=F)senin kurulumunda olduğu gibi zaman "etkisi" bilgilendirici araziler verdi düşündüm . Bunu mu demek istediniz: rms
DWin

Evet, Schoenfeld kalıntıları zaman değişimi hakkında iyi bir fikir veriyor, ancak insanların bunu anlamakta zorlanabileceğini düşünüyorum. Grafik, anladığım kadarıyla, modelim tarafından açıklanmayan artık varyasyonu veriyor. Ben y ekseni üzerinde tam değişken etkisi ve x ekseni üzerinde zaman var bir arsa olsa da, ben hem tablo hem de arsa bakmak zorunda değilsiniz çünkü bu yorumlamak için daha kolay olacağını düşünüyorum tehlikeyi belirli bir zamanda elde etmek için ... Evet, AIC () ile çalışmadığı için coph () değil cph () demek istedim
Max Gordon

Ayrıca, bu I (değişken * zaman) çok düz ileri ve sezgisel görünüyor - istatistikçi olmayan olarak düşündüğüm - neyi kaçırdım? ?
Max Gordon

6

Bunun cevabını ne @ DWin'in ne de @ Zach'in cevapları zamana göre değişen katsayıların nasıl modelleneceğini tam olarak cevapladığı için değiştirdim. Son zamanlarda bunun hakkında bir yazı yazdım . İşte özü.

h(t)

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

f(t)S(t)0

time0S(t)

Diğer zaman noktalarında giren konuların izin ne zaman değiştirmeniz gerekir Survdan Surv(time, status)için Surv(start_time, end_time, status). Sonuçla end_timegüçlü bir şekilde ilişkilendirilse de start_time, şimdi bir etkileşim terimi olarak mevcuttur (tıpkı orijinal önerilerde ima edildiği gibi). Düzenli bir ayarda, start_timedaha sonra görünen birkaç konu dışında 0 olur, ancak her bir gözlemi birkaç döneme bölerek aniden sıfır olmayan bol başlangıç ​​sürelerine sahibiz. Tek fark, her gözlemin, son gözlem hariç hepsinin sansürsüz bir sonuç seçeneğine sahip olduğu birden çok kez gerçekleşmesidir.

Pratikte zaman ayrımı

Bu zaman dilimini kolaylaştıran Greg paketini CRAN'da yayınladım . İlk önce bazı teorik gözlemlerle başlıyoruz:

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

Bunu grafiksel olarak * bir olayın göstergesi olarak gösterebiliriz:

enter image description here

timeSplitterAşağıdaki gibi uygularsak :

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

Aşağıdakileri alıyoruz:

enter image description here

Gördüğünüz gibi her nesne, son zaman aralığının gerçek olay durumunu içerdiği birden fazla olaya bölünmüştür. Bu, artık basit :etkileşim terimlerine sahip modeller oluşturmamıza izin veriyor ( *bu, genişlediğinden kullanmayın time + var + time:varve zamanla ilgilenmiyoruz). I()Doğrusallığı zamanla kontrol etmek istiyorsanız, genellikle bir spline eklediğim ve daha sonra kullanarak görüntülediğim ayrı bir zaman etkileşimi değişkeni oluşturuyorum, ancak işlevi kullanmaya gerek yoktur rms::contrast. Her neyse, regresyon çağrınız şimdi şöyle görünmelidir:

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

Hayatta kalma paketinin ttişlevini kullanma

Ayrıca, zamana bağlı katsayıları ttfonksiyonu kullanarak doğrudan hayatta kalma paketinde modellemenin bir yolu da vardır . Prof. Therneau onun içinde konuya kapsamlı bir tanıtım sağlar skeç . Ne yazık ki büyük veri kümelerinde bellek sınırlamaları nedeniyle bunu yapmak zordur. ttFonksiyonun zamanı, süreçte büyük bir matris oluşturan çok ince parçalara ayırdığı anlaşılıyor .


2

Yuvarlanan bir pencereden doğrusal bir regresyon çalıştırmak için katsayılarınızın zaman içinde değişmesine olanak tanıyacak PerformanceAnalytics'deki Apply.rolling işlevini kullanabilirsiniz .

Örneğin:

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

Bu, diğer işlevlerle de çalışır.


Cevabınız için teşekkür ederim, sanırım hareketli bir zaman penceresi benim yaklaşımlarım kadar iyi çalışmalı. Ben senin örnek çalıştırmak olsa alamıyorum, tam olarak nasıl uygulanacağını bilmek, lütfen sTRACE örneğime dayalı bir örnek verebilir misiniz?
Max Gordon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.