Decision whether to use Markov or Semi-Markov
#state arrival extended (semi-)Markov to mean that the i → j transition hazard depends on thetime of arrival at state i.
#Build a Cox proportional hazard model including treatment and time in previous state as covariates
tab_cox_markov<- data.frame()
for (i in c(2:max(trans_matrix,na.rm=T))){
coxph(Surv(Tstart,Tstop,status)~factor(tipo_de_plan_res_1)+Tstart_yr,
data=subset(ms_d_match_surv_res, trans==i) %>% dplyr::mutate(Tstart_yr=Tstart/365.25),method = "breslow") %>%
assign(paste0("CoxMarkov",i),.,envir=.GlobalEnv)
round(exp(coef(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("HR",i),.,envir=.GlobalEnv)
round(exp(confint(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
round(coef(summary(get(paste0("CoxMarkov",i))))[,5],4)%>% assign(paste0("P",i),.,envir=.GlobalEnv)
data.frame(get(paste0("CI",i))) %>% dplyr::rename("Lower 95% CI"="X2.5..","Upper 95% CI"="X97.5..")%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
tab_cox_markov_add<- cbind.data.frame(plots[i, "title"],get(paste0("HR",i)),get(paste0("CI",i)),get(paste0("P",i)))
tab_cox_markov<-rbind.data.frame(tab_cox_markov,tab_cox_markov_add)
}
invisible(formatC(c(exp(coef(get(paste0("CoxMarkov",2))))[2], exp(confint(get(paste0("CoxMarkov",2))))[2,]), format = "f", digits = 8))
invisible(scales::scientific(c(0.000416, 0.000240, 0.000592), digits = 3))
invisible(scales::scientific(c(0.000329, 0.00000404, 0.000653), digits = 3))
tab_cox_markov2<- data.frame()
for (i in c(2:max(trans_matrix,na.rm=T))){
coxph(Surv(time,status)~factor(tipo_de_plan_res_1)+Tstart_yr,
data=subset(ms_d_match_surv_res, trans==i) %>% dplyr::mutate(Tstart_yr=Tstart/365.25),method = "breslow") %>%
assign(paste0("CoxMarkov",i),.,envir=.GlobalEnv)
round(exp(coef(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("HR",i),.,envir=.GlobalEnv)
round(exp(confint(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
round(coef(summary(get(paste0("CoxMarkov",i))))[,5],4)%>% assign(paste0("P",i),.,envir=.GlobalEnv)
data.frame(get(paste0("CI",i))) %>% dplyr::rename("Lower 95% CI"="X2.5..","Upper 95% CI"="X97.5..")%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
tab_cox_markov_add<- cbind.data.frame(plots[i, "title"],get(paste0("HR",i)),get(paste0("CI",i)),get(paste0("P",i)))
tab_cox_markov2<-rbind.data.frame(tab_cox_markov2,tab_cox_markov_add)
}
#2021-08-21: con renewal da lo mismo
tab_cox_markov %>%
data.table(keep.rownames=T) %>%
dplyr::rename("Terms"="rn", "Transition"="plots[i, \"title\"]",
"HR"="get(paste0(\"HR\", i))","P"="get(paste0(\"P\", i))") %>%
dplyr::mutate(Terms=dplyr::case_when(grepl("tipo_de_", Terms)~"Setting (Residential)",
grepl("Tstart",Terms)~"Time in previous state(in years)")) %>%
dplyr::mutate(P=ifelse(P<.001,"<.001",sprintf("%1.3f",P))) %>%
dplyr::rename("Sig."="P") %>%
dplyr::mutate(`95% CIs`=paste0(sprintf("%2.2f",`Lower 95% CI`),", ",sprintf("%2.2f",`Upper 95% CI`))) %>%
dplyr::select(-`Lower 95% CI`,-`Upper 95% CI`) %>%
dplyr::select(Transition, Terms, HR, `95% CIs`, Sig.) %>%
knitr::kable(format= "html", format.args= list(decimal.mark= ".", big.mark= ","),
caption="Table 11. PH Model incluiding time in previous state & Setting as a covariate",
align= c("c",rep('c', 5)))%>%
#kableExtra::pack_rows("Three-states", 1, 2) %>%
#kableExtra::pack_rows("Four-states", 3, 4) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),font_size= 11)%>%
kableExtra::kable_classic() %>%
kableExtra::scroll_box(width = "100%", height = "350px")
Table 11. PH Model incluiding time in previous state & Setting as a
covariate
Transition
|
Terms
|
HR
|
95% CIs
|
Sig.
|
Readmission to Second Readmission
|
Setting (Residential)
|
1.04
|
0.95, 1.13
|
0.451
|
Readmission to Second Readmission
|
Time in previous state(in years)
|
1.18
|
1.13, 1.22
|
<.001
|
Second to Third Readmission
|
Setting (Residential)
|
1.06
|
0.90, 1.25
|
0.459
|
Second to Third Readmission
|
Time in previous state(in years)
|
1.16
|
1.09, 1.24
|
<.001
|
Third to Fourth Readmission
|
Setting (Residential)
|
1.09
|
0.82, 1.46
|
0.551
|
Third to Fourth Readmission
|
Time in previous state(in years)
|
1.09
|
0.97, 1.23
|
0.148
|
#a variable appears on both the left and right sides of the formula
#this warning should be normal, since we are dealing with time to arrival at a determined state.
Time for this code chunk to run: 0 minutes
#state arrival extended (semi-)Markov to mean that the i → j transition hazard depends on thetime of arrival at state i.
#Build a Cox proportional hazard model including treatment and time in previous state as covariates
tab_cox_markov_9s<- data.frame()
for (i in c(3:max(trans_matrix2,na.rm=T))){
coxph(Surv(Tstart,Tstop,status)~factor(tipo_de_plan_res_1)+Tstart_yr,
data=subset(ms_d_match_surv_oct_2022, trans==i) %>% dplyr::mutate(Tstart_yr=Tstart/365.25),method = "breslow") %>%
assign(paste0("CoxMarkov",i),.,envir=.GlobalEnv)
round(exp(coef(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("HR",i),.,envir=.GlobalEnv)
round(exp(confint(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
round(coef(summary(get(paste0("CoxMarkov",i))))[,5],4)%>% assign(paste0("P",i),.,envir=.GlobalEnv)
data.frame(get(paste0("CI",i))) %>% dplyr::rename("Lower 95% CI"="X2.5..","Upper 95% CI"="X97.5..")%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
tab_cox_markov_add2<- cbind.data.frame(plots2[i, "title"],get(paste0("HR",i)),get(paste0("CI",i)),get(paste0("P",i)))
tab_cox_markov_9s<-rbind.data.frame(tab_cox_markov_9s,tab_cox_markov_add2)
}
invisible(formatC(c(exp(coef(get(paste0("CoxMarkov",2))))[2], exp(confint(get(paste0("CoxMarkov",2))))[2,]), format = "f", digits = 8))
invisible(scales::scientific(c(0.000416, 0.000240, 0.000592), digits = 3))
invisible(scales::scientific(c(0.000329, 0.00000404, 0.000653), digits = 3))
tab_cox_markov2_9s<- data.frame()
for (i in c(3:max(trans_matrix2,na.rm=T))){
coxph(Surv(time,status)~factor(tipo_de_plan_res_1)+Tstart_yr,
data=subset(ms_d_match_surv_oct_2022, trans==i) %>% dplyr::mutate(Tstart_yr=Tstart/365.25),method = "breslow") %>%
assign(paste0("CoxMarkov",i),.,envir=.GlobalEnv)
round(exp(coef(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("HR",i),.,envir=.GlobalEnv)
round(exp(confint(get(paste0("CoxMarkov",i)))),2)%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
round(coef(summary(get(paste0("CoxMarkov",i))))[,5],4)%>% assign(paste0("P",i),.,envir=.GlobalEnv)
data.frame(get(paste0("CI",i))) %>% dplyr::rename("Lower 95% CI"="X2.5..","Upper 95% CI"="X97.5..")%>% assign(paste0("CI",i),.,envir=.GlobalEnv)
tab_cox_markov_add22<- cbind.data.frame(plots2[i, "title"],get(paste0("HR",i)),get(paste0("CI",i)),get(paste0("P",i)))
tab_cox_markov2_9s<-rbind.data.frame(tab_cox_markov2_9s,tab_cox_markov_add22)
}
#2021-08-21: con renewal da lo mismo
tab_cox_markov_9s %>%
data.table(keep.rownames=T) %>%
dplyr::rename("Terms"="rn", "Transition"="plots2[i, \"title\"]",
"HR"="get(paste0(\"HR\", i))","P"="get(paste0(\"P\", i))") %>%
dplyr::mutate(Terms=dplyr::case_when(grepl("tipo_de_", Terms)~"Setting (Residential)",
grepl("Tstart",Terms)~"Time in previous state(in years)")) %>%
dplyr::mutate(P=ifelse(P<.001,"<.001",sprintf("%1.3f",P))) %>%
dplyr::rename("Sig."="P") %>%
dplyr::mutate(`95% CIs`=paste0(sprintf("%2.2f",`Lower 95% CI`),", ",sprintf("%2.2f",`Upper 95% CI`))) %>%
dplyr::select(-`Lower 95% CI`,-`Upper 95% CI`) %>%
dplyr::select(Transition, Terms, HR, `95% CIs`, Sig.) %>%
knitr::kable(format= "html", format.args= list(decimal.mark= ".", big.mark= ","),
caption="Table 11. PH Model incluiding time in previous state & Setting as a covariate",
align= c("c",rep('c', 5)))%>%
#kableExtra::pack_rows("Three-states", 1, 2) %>%
#kableExtra::pack_rows("Four-states", 3, 4) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),font_size= 11)%>%
kableExtra::kable_classic() %>%
kableExtra::scroll_box(width = "100%", height = "350px")
Table 11. PH Model incluiding time in previous state & Setting as a
covariate
Transition
|
Terms
|
HR
|
95% CIs
|
Sig.
|
Completion to Readmission
|
Setting (Residential)
|
1.69
|
1.51, 1.90
|
<.001
|
Completion to Readmission
|
Time in previous state(in years)
|
1.87
|
1.67, 2.10
|
<.001
|
Non-completion to Readmission
|
Setting (Residential)
|
1.55
|
1.45, 1.65
|
<.001
|
Non-completion to Readmission
|
Time in previous state(in years)
|
2.23
|
2.06, 2.41
|
<.001
|
Readmission to Second Readmission (TC)
|
Setting (Residential)
|
1.16
|
0.93, 1.44
|
0.199
|
Readmission to Second Readmission (TC)
|
Time in previous state(in years)
|
1.17
|
1.08, 1.27
|
<.001
|
Readmission to Second Readmission (TNC)
|
Setting (Residential)
|
1.00
|
0.90, 1.12
|
0.938
|
Readmission to Second Readmission (TNC)
|
Time in previous state(in years)
|
1.19
|
1.13, 1.25
|
<.001
|
Second to Third Readmission (TC)
|
Setting (Residential)
|
0.91
|
0.61, 1.37
|
0.661
|
Second to Third Readmission (TC)
|
Time in previous state(in years)
|
1.34
|
1.16, 1.56
|
<.001
|
Second to Third Readmission (TNC)
|
Setting (Residential)
|
1.14
|
0.94, 1.38
|
0.174
|
Second to Third Readmission (TNC)
|
Time in previous state(in years)
|
1.12
|
1.03, 1.21
|
0.005
|
#a variable appears on both the left and right sides of the formula
#this warning should be normal, since we are dealing with time to arrival at a determined state.
Time for this code chunk to run: 0 minutes
overall_test<-function(x){
x<-deparse(substitute(x))
paste0("Chi2(", get(x)[["Nsub"]],")=",
round(get(x)[["orig_ch_stat"]],2),", p=",
sprintf("%1.4f",get(x)[["p_ch_stat_wb"]]))
}
#_#_#_#__#_#_#_#_#_#__###### markov test ##### _#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_
ms_d_match_surv_res_tm<- ms_d_match_surv_res
ms_d_match_surv_oct_2022_tm<- ms_d_match_surv_oct_2022
attr(ms_d_match_surv_res_tm, "trans")<-trans_matrix
attr(ms_d_match_surv_oct_2022_tm, "trans")<-trans_matrix2
#Time grid
tseq <- seq(1,1837,by=30)
#Three approaches to testing are considered; i) A simple method based on including
#time of entry into the state as a covariate in a Cox model for each transition
#intensity ii) Use of the stratified version of the Commenges-Andersen test 2
#for a univariate frailty, and iii) A novel class of tests based on families of
#log-rank statistics, where patients are grouped by their state occupancy at landmark times.
invisible("Pruebas")
start_time <- Sys.time()
#ms_d_match_surv_oct_2022_tm[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
cox_markov_test_prueba12<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm,
formula="tipo_de_plan_res_1", id = "id", transition=1, grid=tseq, B=10)
overall_test(cox_markov_test_prueba12)
## [1] "Chi2(22452)=0, p=0.0000"
Time for this code chunk to run: 0 minutes
cox_markov_test_prueba13<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, formula="tipo_de_plan_res_1", id = "id", transition=2, grid=tseq, B=200)
overall_test(cox_markov_test_prueba13)
## [1] "Chi2(22452)=0, p=0.0000"
cox_markov_test_prueba24<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, formula="tipo_de_plan_res_1", id = "id", transition=3, grid=tseq, B=200)
overall_test(cox_markov_test_prueba24)
## [1] "Chi2(5356)=35.3, p=0.0100"
cox_markov_test_prueba35<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, formula="tipo_de_plan_res_1", id = "id", transition=4, grid=tseq, B=200)
overall_test(cox_markov_test_prueba35)
## [1] "Chi2(13067)=68.71, p=0.0000"
end_time <- Sys.time()
print("Time taken in process")
## [1] "Time taken in process"
end_time - start_time
## Time difference of 5.317755 hours
#The model considered the transition from intermediate states to our absorbing state (being readmitted at the fourth time) is explained by the time spent in the previous health state. This covariate (time in the previous state) was shown to be statistically significant (p<.001); results indicated a longer duration spent in the first treatment is associated with increased risk of readmission. Therefore, a semi-Markov (called a Markov renewal model) or clock reset approach should be undertaken for both models.
Time for this code chunk to run: 0.1 minutes
#ms_d_match_surv_oct_2022_tm[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
cox_markov_test_prueba46<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm,#[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
formula="tipo_de_plan_res_1", id = "id", transition=5, grid=tseq, B=200)
overall_test(cox_markov_test_prueba46)
## [1] "Chi2(1518)=8.42, p=0.0050"
cox_markov_test_prueba57<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, #[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
formula="tipo_de_plan_res_1", id = "id", transition=6, grid=tseq, B=200)
overall_test(cox_markov_test_prueba57)
## [1] "Chi2(4046)=22.96, p=0.0000"
cox_markov_test_prueba68<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, #[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
formula="tipo_de_plan_res_1", id = "id", transition=7, grid=tseq, B=200)
overall_test(cox_markov_test_prueba68)
## [1] "Chi2(447)=8.85, p=0.0100"
cox_markov_test_prueba79<-
mstate::MarkovTest(ms_d_match_surv_oct_2022_tm, #[which(ms_d_match_surv_oct_2022_tm$id %in% 1:20),],
formula="tipo_de_plan_res_1", id = "id", transition=8, grid=tseq, B=200)
overall_test(cox_markov_test_prueba79)
## [1] "Chi2(1305)=9.21, p=0.0100"
end_time2 <- Sys.time()
Time for this code chunk to run: 0.6 minutes