Зависящие от времени коэффициенты в R - как это сделать?


17

Обновление : Извините за другое обновление, но я нашел несколько возможных решений с дробными полиномами и конкурирующим пакетом риска, с которым мне нужна помощь.


Проблема

Я не могу найти простой способ сделать зависящий от времени анализ коэффициентов в R. Я хочу иметь возможность взять мой коэффициент переменных и превратить его в зависящий от времени коэффициент (не переменный), а затем построить график зависимости от времени:

βmy_variable=β0+β1t+β2t2...

Возможные решения

1) Разделение набора данных

Я посмотрел на этот пример (часть 2 лабораторного занятия), но создание отдельного набора данных кажется сложным, вычислительно дорогостоящим и не очень интуитивно понятным ...

2) Модели пониженного ранга - пакет coxvc

Пакет coxvc предоставляет элегантный способ решения проблемы - вот руководство . Проблема в том, что автор больше не разрабатывает пакет (последняя версия с 23.05.2007), после некоторого разговора по электронной почте я получил пакет для работы, но один запуск занял 5 часов в моем наборе данных (140 000 записи) и дает экстремальные оценки в конце периода. Вы можете найти немного обновленный пакет здесь - я в основном только что обновил функцию сюжета.

Это может быть просто вопрос настройки, но поскольку программное обеспечение не может легко обеспечить доверительные интервалы, а процесс занимает так много времени, я сейчас смотрю на другие решения.

3) Timereg пакет

Впечатляющий пакет timereg также решает проблему, но я не уверен, как его использовать, и он не дает мне четкого сюжета.

4) Модель дробного полиномиального времени (FPT)

Я нашел отличную диссертацию Аники Буххольц «Оценка изменяющихся во времени долгосрочных эффектов терапии и прогностических факторов» , которая отлично справляется с различными моделями. Она приходит к выводу, что предлагаемый FPT Sauerbrei и др. Представляется наиболее подходящим для зависящих от времени коэффициентов:

FPT очень хорошо обнаруживает изменяющиеся во времени эффекты, в то время как подход с уменьшенным рангом приводит к слишком сложным моделям, поскольку он не включает выбор изменяющихся во времени эффектов.

Исследование кажется очень полным, но оно для меня немного недосягаемо. Я также немного удивляюсь, так как она работает с Sauerbrei. Хотя это кажется здравым, и я думаю, что анализ мог бы быть сделан с пакетом mfp, но я не уверен, как.

5) пакет cmprsk

Я думал о проведении моего конкурирующего анализа рисков, но расчеты были трудоемкими, поэтому я переключился на регулярную регрессию Кокса. У crr есть опция для зависящих от времени ковариат:

....
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 . Я думаю, что результаты в порядке, но я не думаю, что смогу объяснить график таймкокса - он кажется сложным ...

Мои (текущие) вопросы

  • Как мне выполнить анализ FPT в R?
  • Как мне использовать ковариату времени в cmprsk?
  • Как мне построить результат (желательно с доверительными интервалами)?

3
Yзнак равноИксβмYYзнак равноИксβ0+ИксTβ1+ИксT2β2y~xy~x*(t+t^2)-ty~x+x:t+x:t^2

Я думал, что вторая часть: «2. Модель детерминированных зависящих от времени ковариат для проверки предположения PH» будет частью, касающейся моего вопроса. Я надеялся сделать что-то из формулы, которую вы описываете, но когда я попробовал это, я либо получил ошибку, либо отдельную переменную времени ... Я получил низкое значение p для времени :-D
Макс Гордон,

@ max-gordon, ваша переменная ответа - это величина или время, прошедшее до появления четного числа? Потому что большинство методов, которые вы цитируете, специально для данных о времени события.
f1r3br4nd

@ f1r3br4nd: Это количество (возраст в моем исследовании), где опасность непропорциональна, то есть она меняется со временем в моей модели времени до события. В конце концов я решил разделиться на два разных периода времени, так как я не был в восторге от создания трехмерного графика - это никогда бы не прошло мимо рецензентов ...
Макс Гордон

Существует разница между зависящими от времени / изменяющимися предикторами и временным взаимодействием. Большинство переменных зависят от времени (пол является исключением). Если у вас есть одно наблюдение на человека, то у вас будет мало или нет шансов провести анализ, зависящий от времени / изменяющийся. Метод Андерсона-Гилла является наиболее часто используемым для анализа выживаемости в зависимости от времени. Преимущество методов, зависящих от времени, состоит в том, что значения во время наблюдения могут быть более предсказуемыми, чем исходные значения. Вторая ситуация, предикторы, взаимодействующие во времени, - это просто тесты предположения PH.
Адам Робинссон

Ответы:


8

@mpiktas приблизился к предложению выполнимой модели, однако термин, который нужно использовать для квадратичного по времени = t, будет таким I(t^2)). Это так, потому что в R интерпретация формулы «^» создает взаимодействия и не выполняет возведения в степень, поэтому взаимодействие «t» с «t» является просто «t». (Разве это не должно быть перенесено в SO с тегом [r]?)

Об альтернативах этому процессу, который кажется мне несколько сомнительным для целей вывода, и который, вероятно, соответствует вашему интересу к использованию вспомогательных функций в пакетах rre / hmisc Харрелла, см. «Стратегии регрессионного моделирования» Харрелла. Он упоминает (но только мимоходом, хотя он цитирует некоторые из своих собственных работ), построение сплайна соответствует времени, чтобы смоделировать опасности в форме ванны. В его главе, посвященной параметрическим моделям выживания, описываются различные методы построения графиков для проверки предположений о пропорциональных опасностях и для изучения линейности предполагаемых воздействий лесозаготовительных явлений на временной шкале.

Изменить: дополнительная опция заключается в использовании coxph параметра 'tt', описанного как «необязательный список функций преобразования времени».


Я согласен, что это, вероятно, следует перенести в тег SO [r].
Зак

+1 за ваш ответ, я не знал, что это будет так сложно ответить. Кажется, это общая проблема, возможно, этот вопрос больше связан с кодированием, чем вы, и, возможно, вы правы в том, что SO - лучший выбор. Я попробовал вашу формулу, кажется, что VF + I ( журнал VF (время)) отлично подходит, я пытался просто VF time и vf * time ^ 2, но журнал дал тарифу самое низкое значение p. Я попытался запустить его с помощью функции cph (), чтобы получить AIC, но он выдал ошибку :( У вас есть идея, как составить график оценки?
Макс Гордон

Я думал, что check <- cox.zph(fit1); print(check); plot(check, resid=F)в твоих настройках приведены информативные сюжеты того времени «Эффект». Вы имели в виду cph () из пакета rms или coxph из списка «Выживание»?
DWin

Да, остатки Шенфельда дают хорошее представление об изменении времени, но я думаю, что людям может быть трудно понять это. Сюжет дает, насколько я понимаю, остаточное отклонение, не объясненное моей моделью. Хотелось бы, чтобы график, на котором у меня был полный эффект переменной на оси у, и время на оси х, я считаю, что это будет легче интерпретировать, поскольку вам не нужно смотреть как на таблицу, так и на график. чтобы получить опасность в определенный момент времени ... Да, я имел в виду cph (), а не coxph (), так как этот не работает с AIC ()
Макс Гордон

Я также немного смущен тем, почему я нашел все сложные методы, описанные в моем вопросе, в то время как это я (переменная * время) кажется очень прямым и интуитивным - как не статистик, я думаю - что я пропустил ?
Макс Гордон

5

Я изменил ответ на этот вопрос, поскольку ни ответы @ DWin, ни @ Zach не дают полного ответа на то, как моделировать изменяющиеся во времени коэффициенты. Я недавно написал пост об этом. Вот суть этого.

h(t) . Он определяется как:

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

f(t)S(t)0 .

time0S(t) при рассмотрении опасности до 1 года. Через 1 год мы можем включить Питера.

При разрешении субъектов входить в другие моменты времени мы должны изменить 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функции. Профессор Терно подробно описывает этот предмет в своей виньетке . К сожалению, в больших наборах данных это трудно сделать из-за ограничений памяти. Кажется, что 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, чтобы я точно знал, как его реализовать?
Макс Гордон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.