Atualização : desculpe por outra atualização, mas encontrei algumas soluções possíveis com polinômios fracionários e o pacote de risco concorrente com o qual preciso de ajuda.
O problema
Não consigo encontrar uma maneira fácil de fazer uma análise de coeficiente dependente do tempo em R. Quero poder pegar o coeficiente de minhas variáveis e transformá-lo em um coeficiente dependente de tempo (não variável) e, em seguida, plotar a variação contra o tempo:
Soluções possíveis
1) Dividindo o conjunto de dados
Analisei este exemplo (veja a parte 2 da sessão de laboratório), mas a criação de um conjunto de dados separado parece complicada, onerosa e computacionalmente pouco intuitiva ...
2) Modelos com classificação reduzida - o pacote coxvc
O pacote coxvc fornece uma maneira elegante de lidar com o problema - aqui está um manual . O problema é que o autor não está mais desenvolvendo o pacote (a última versão é desde 23/05/2007), após algumas conversas por e-mail, consegui que o pacote funcionasse, mas uma execução levou 5 horas no meu conjunto de dados (140 000 entradas) e fornece estimativas extremas no final do período. Você pode encontrar um pacote ligeiramente atualizado aqui - eu apenas atualizei a função plot.
Pode ser apenas uma questão de ajustes, mas como o software não fornece facilmente intervalos de confiança e o processo é tão demorado, agora estou procurando outras soluções.
3) O pacote timereg
O impressionante pacote timereg também aborda o problema, mas não tenho certeza de como usá-lo e não me fornece uma trama suave.
4) Modelo de tempo polinomial fracionário (FPT)
Encontrei a excelente dissertação de Anika Buchholz sobre "Avaliação dos efeitos de longo prazo de terapias e fatores prognósticos que variam no tempo", que faz um excelente trabalho cobrindo diferentes modelos. Ela conclui que o TPF proposto por Sauerbrei et al parece ser o mais apropriado para os coeficientes dependentes do tempo:
O FPT é muito bom na detecção de efeitos que variam no tempo, enquanto a abordagem Classificação Reduz resulta em modelos muito complexos, pois não inclui a seleção de efeitos que variam no tempo.
A pesquisa parece muito completa, mas está um pouco fora do meu alcance. Também estou me perguntando, já que ela trabalha com Sauerbrei. Parece bom e acho que a análise poderia ser feita com o pacote mfp, mas não sei como.
5) O pacote cmprsk
Eu estava pensando em fazer minha análise de risco concorrente, mas os cálculos foram demorados, então mudei para a regressão cox regular. O crr tem uma opção para covariáveis dependentes do tempo:
....
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
....
Há o exemplo quadrático, mas não sou muito fiel ao local onde a hora realmente aparece e não tenho certeza de como exibi-la. Eu também olhei para o arquivo test.R, mas o exemplo é basicamente o mesmo ...
Meu código de exemplo
Aqui está um exemplo que eu uso para testar as diferentes possibilidades
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))
O código resulta nos seguintes gráficos: Comparação de configurações diferentes para coxvc e dos gráficos coxvc e timecox . Acho que os resultados estão bons, mas acho que não vou conseguir explicar o gráfico da timecox - parece complexo ...
Minhas perguntas (atuais)
- Como faço a análise do FPT em R?
- Como uso a covariável de tempo no cmprsk?
- Como plotar o resultado (de preferência com intervalos de confiança)?
fonte
y~x
y~x*(t+t^2)-t
y~x+x:t+x:t^2
Respostas:
O @mpiktas chegou perto de oferecer um modelo viável, no entanto, o termo que precisa ser usado para o quadrático no tempo = t seria
I(t^2))
. Isso ocorre porque em R a interpretação da fórmula de "^" cria interações e não realiza exponenciação; portanto, a interação de "t" com "t" é apenas "t". (Isso não deve ser migrado para o SO com uma tag [r]?)Para alternativas a esse processo, que me parece um tanto duvidoso para fins de inferência e que provavelmente se encaixa no seu interesse em usar as funções de suporte nos pacotes rms / Hmisc da Harrell, consulte "Estratégias de modelagem de regressão" da Harrell. Ele menciona (mas apenas de passagem, embora cite alguns de seus próprios artigos) a construção de ajustes de spline na escala de tempo para modelar riscos em forma de banheira. Seu capítulo sobre modelos de sobrevivência paramétricos descreve uma variedade de técnicas de plotagem para verificar pressupostos de riscos proporcionais e para examinar a linearidade dos efeitos estimados de riscos log na escala de tempo.
Editar: Uma opção adicional é usar
coxph
o parâmetro 's' tt 'descrito como uma "lista opcional de funções de transformação no tempo".fonte
check <- cox.zph(fit1); print(check); plot(check, resid=F)
como na sua configuração, fornecemos gráficos informativos do tempo "efeito". Você quis dizer cph (), que é do pacote rms ou coxph, da sobrevivência?Alterei a resposta para isso, pois nem as respostas do @ DWin nem do @ Zach respondem totalmente a como modelar coeficientes variáveis no tempo. Eu escrevi recentemente um post sobre isso. Aqui está a essência disso.
O conceito central no modelo de regressão de Cox é a função de risco , . É definido como:h(t)
Onde é o risco de ocorrer um evento a qualquer momento, enquanto é a probabilidade de sobreviver a essa tarifa. O número é, portanto, uma fração com um intervalo teórico de a .f(t) S(t) 0 ∞
Uma característica interessante da função de risco é que podemos incluir observações em outros momentos além dotime0 S(t)
Ao permitir que os sujeitos entrem em outros momentos, devemos alterar
Surv
de deSurv(time, status)
paraSurv(start_time, end_time, status)
. Enquanto oend_time
está fortemente correlacionado com o resultado,start_time
agora está disponível como um termo de interação (como sugerido nas sugestões originais). Em um ambiente regular, o valorstart_time
é 0, exceto em alguns assuntos que aparecem mais tarde, mas, como dividimos cada observação em vários períodos, de repente temos muitos horários de início diferentes de zero. A única diferença é que cada observação ocorre várias vezes, onde todas, exceto a última, têm a opção de um resultado não censurado.Divisão de tempo na prática
Acabei de publicar no CRAN o pacote Greg que facilita essa divisão do tempo . Primeiro começamos com algumas observações teóricas:
Podemos mostrar isso graficamente com * sendo um indicador de evento:
Se aplicarmos o
timeSplitter
seguinte:Temos o seguinte:
Como você pode ver, cada objeto foi dividido em vários eventos, nos quais o último período contém o status real do evento. Isso nos permite criar modelos que têm
:
termos simples de interação (não use o*
que ele expandetime + var + time:var
e não estamos interessados no tempo em si). Não há necessidade de usar aI()
função, embora se você deseja verificar a não linearidade com o tempo, muitas vezes crio uma variável de interação com o tempo separada à qual adiciono um spline e exibo usandorms::contrast
. De qualquer forma, sua chamada de regressão agora deve ficar assim:Usando a
tt
função do pacote de sobrevivênciaTambém existe uma maneira de modelar coeficientes dependentes do tempo diretamente no pacote de sobrevivência usando a
tt
função O Prof. Therneau fornece uma introdução completa ao assunto em sua vinheta . Infelizmente, em grandes conjuntos de dados, isso é difícil de executar devido a limitações de memória. Parece que att
função divide o tempo em partes muito finas, gerando no processo uma enorme matriz.fonte
Você pode usar a função apply.rolling no PerformanceAnalytics para executar uma regressão linear através de uma janela contínua, o que permitirá que seus coeficientes variem ao longo do tempo.
Por exemplo:
Isso funciona com outras funções também.
fonte