R의 시간 의존 계수-어떻게해야합니까?


17

업데이트 : 다른 업데이트에 대해 죄송하지만 분수 다항식과 도움이 필요한 경쟁 위험 패키지가있는 가능한 솔루션을 찾았습니다.


문제

시간 종속 계수 분석을 수행하는 쉬운 방법을 찾을 수 없습니다 .R입니다. 변수 계수를 가져 와서 시간 의존 계수 (변수가 아닌)로 수행 한 다음 시간에 대한 변동을 플롯 할 수 있기를 원합니다.

βmy_V아르 자형나는이자형=β0+β1+β22...

가능한 해결책

1) 데이터 셋 분할

예제 (실험실 세션의 2 부)를 살펴 봤지만 별도의 데이터 집합을 만드는 것은 복잡하고 계산 비용이 많이 들고 직관적이지 않은 것으로 보입니다.

2) 감소 된 순위 모델-coxvc 패키지

coxvc 패키지는 이 문제를 처리하는 우아한 방법을 제공합니다 - 여기의 매뉴얼 . 문제는 저자가 더 이상 패키지를 개발하지 않고 있다는 것입니다 (마지막 버전은 2007 년 5 월 23 일 이후 임). 전자 메일 대화 후 패키지가 작동했지만 데이터 세트에서 한 번의 실행에 5 시간이 걸렸습니다 (140 000 기간이 끝날 때 극단적 인 견적을 제공합니다. 약간 업데이트 된 패키지를 여기서 찾을 수 있습니다 -나는 대부분 플롯 기능을 업데이트했습니다.

그것은 조정의 문제 일지 모르지만 소프트웨어는 쉽게 신뢰 구간을 제공하지 않으며 프로세스가 너무 시간이 걸리기 때문에 지금 다른 솔루션을 찾고 있습니다.

3) timereg 패키지

인상적인 timereg 패키지 도 문제를 해결하지만 사용 방법을 잘 모르겠으며 매끄러운 음모를 나타내지 않습니다.

4) 분수 다항식 시간 (FPT) 모델

나는 다양한 모델을 다루는 훌륭한 일을하는 "시간의 평가 – 치료와 장기적 영향의 다양한 영향 평가"에 관한 Anika Buchholz의 훌륭한 논문을 발견했습니다 . 그녀는 Sauerbrei et al이 제안한 FPT 가 시간 의존 계수에 가장 적합한 것으로 보인다고 결론을 내립니다 .

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의 플롯. 나는 결과가 괜찮다고 생각하지만 타임 콕스 그래프를 설명 할 수 없다고 생각합니다. 복잡한 것 같습니다 ...

내 (현재) 질문

  • R에서 FPT 분석은 어떻게합니까?
  • cmprsk에서 시간 공변량을 어떻게 사용합니까?
  • 결과를 플롯하는 방법 (바람직하게는 신뢰 구간 포함)은 어떻게됩니까?

3
와이=엑스β미디엄와이와이=엑스β0+엑스β1+엑스2β2y~xy~x*(t+t^2)-ty~x+x:t+x:t^2

두 번째 부분 : "2. PH 가정을 확인하기위한 모델 결정적 시간 종속 공변량"이 내 질문을 다루는 부분이라고 생각했습니다. 나는 당신이 묘사 한 수식을하고 싶었지만 그것을 시도했을 때 오류 나 별도의 시간 변수가 생겼습니다 ...하지만 나는 시간 동안 낮은 p 값을 얻었습니다 :-D
Max Gordon

@ max-gordon, 귀하의 응답 변수가 수량입니까, 심지어 짝수 발생까지 경과 된 시간입니까? 인용하는 대부분의 방법은 특히 이벤트 시간 데이터를위한 것입니다.
f1r3br4nd

@ f1r3br4nd : 위험이 비 비례 적 인 수량 (내 연구의 연령)입니다. 즉, 이벤트 시간 모델에서 시간이 지남에 따라 다릅니다. 결국 저는 3D 그래프를 수행하여 스릴을 느끼지 않았기 때문에 두 개의 다른 시간대로 분할하기로 결정했습니다. – 검토자를 통과 한 적이 없었습니다 ...
Max Gordon

시간 종속 / 가변 예측 변수와 시간 상호 작용에는 차이가 있습니다. 대부분의 변수는 시간에 따라 다릅니다 (성별 예외). 한 사람당 하나의 관측치가있는 경우 시간 의존 / 가변 분석을 수행 할 기회가 거의 없거나 전혀 없습니다. Anderson-Gill의 방법은 시간에 따른 생존 분석에 가장 자주 사용됩니다. 시간 의존적 방법의 장점은 후속 조치 동안의 값이 기준치보다 생존 경험의 예측보다 더 정확할 수 있다는 것입니다. 두 번째 상황, 시간 상호 작용 예측 변수는 단순히 PH 가정의 테스트입니다.
Adam Robinsson

답변:


8

@mpiktas는 실현 가능한 모델을 제공하는 데 가까이 다가 갔지만 time = t의 2 차에 사용해야하는 용어는 다음과 같습니다 I(t^2)). R에서 "^"의 수식 해석은 상호 작용을 생성하고 지수화를 수행하지 않기 때문에 "t"와 "t"의 상호 작용은 "t"일뿐입니다. ([r] 태그를 사용하여 SO로 마이그레이션하지 않아야합니까?)

추론 목적으로 다소 모호한 것으로 보이는이 프로세스에 대한 대안과 Harrell의 rms / Hmisc 패키지에서 지원 기능을 사용하는 데 관심이있는 방법에 대해서는 Harrell의 "회귀 모델링 전략"을 참조하십시오. 그는 욕조 모양의 위험을 모델링하기 위해 시간 척도에 맞는 스플라인을 구성한다고 언급합니다 (그러나 자신의 논문 중 일부를 인용하더라도 통과 할 때만). 파라 메트릭 생존 모델에 대한 그의 장에서는 비례 위험 가정을 확인하고 시간 척도에 대한 추정 로그 위험 효과의 선형성을 조사하기위한 다양한 플로팅 기법을 설명합니다.

편집 : 추가 옵션은 coxph"시간 변환 기능의 선택적 목록"으로 설명 된 'tt'매개 변수 를 사용하는 것 입니다.


나는 이것이 아마도 SO [r] 태그로 옮겨 져야한다는 것에 동의한다.
Zach

귀하의 답변에 +1하여, 이것이 너무 어려운 답변이라는 것을 알지 못했습니다. 일반적인 문제처럼 보일 수 있습니다. 아마도 문제는 코딩 문제보다 더 많은 것이며 SO가 더 나은 선택이 될 수 있습니다. 나는 당신의 공식을 시도했는데 그것은 vf + I (vf log (time))이 잘 맞는 것처럼 보입니다 .vf 시간과 vf * time ^ 2 만 시도 했지만 로그는 가장 낮은 p 값을 제공했습니다. AIC를 얻기 위해 cph () 함수로 실행하려고했지만 오류가 발생했습니다. (추정치에 대한 플롯을 수행하는 방법에 대한 아이디어가 있습니까?
Max Gordon

나는 check <- cox.zph(fit1); print(check); plot(check, resid=F)당신의 셋업에서와 같이 시간 "효과"에 대한 유익한 음모를 줄 것이라고 생각했습니다 . rms 패키지의 cph () 또는 생존의 coxph를 의미합니까?
DWin

예, cho 펠트 잔차는 시간 변화에 대한 좋은 아이디어를 제공하지만 사람들이 그것을 이해하는 데 어려움을 겪을 수 있다고 생각합니다. 플롯은 내 모델에서 설명하지 않은 잔차 변동을 이해하는 것으로 나타납니다. y 축과 x 축의 시간에 완전한 변수 효과가있는 플롯을 원하지만 테이블과 플롯을 모두 볼 필요가 없으므로 해석하기가 더 쉽다고 생각합니다 특정 시점에서 위험을 얻으려면 ... 예 cocph ()가 아니라 cph ()를 의미합니다. 왜냐하면 AIC ()와 작동하지 않기 때문입니다.
Max Gordon

나는 또한 내 질문에 설명 된 모든 복잡한 방법을 찾은 이유와 약간 혼란 스럽습니다.이 I (변수 * 시간)는 매우 직설적이며 직관적입니다-비 통계 학자로서 생각합니다-내가 놓친 것 ?
Max Gordon

5

@DWin 또는 @Zach의 답변이 시변 계수를 모델링하는 방법에 완전히 답변하지 않기 때문에 이에 대한 답변을 변경했습니다. 나는 최근 에 이것에 관한 게시물을 썼습니다 . 여기 요점이 있습니다.

의 핵심 개념 h()

h()=에프()에스()

에프()에스()0

나는미디엄이자형0에스()

다른 시점에 주제를 입력 할 수있게하려면 Surv에서 Surv(time, status)를로 변경해야합니다 Surv(start_time, end_time, status). end_time은 결과와 밀접하게 관련되어 있지만 start_time이제는 원래 제안에서 암시 된 것처럼 상호 작용 용어로 사용할 수 있습니다. 일반 설정에서 start_time나중에 나타나는 몇 가지 주제를 제외하고는 0이지만 각 관측치를 여러 기간으로 나누면 갑자기 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.