Kaplan-Meier survival plots

library(openxlsx)
library(survminer)
## Loading required package: ggplot2
## Loading required package: ggpubr
library(survival)
## 
## Attaching package: 'survival'
## The following object is masked from 'package:survminer':
## 
##     myeloma
data <- read.xlsx("/Users/zhangmengmeng/Desktop/Rmodel/Newmodelcoxx.xlsx", sheet = 5)
Newmodelcoxx <- data
colnames(data)
##  [1] "Number"       "outcome"      "genders"      "age"          "BMI"         
##  [6] "typeofdrugs"  "injurytype"   "latency"      "WBC"          "PLT"         
## [11] "ALTonset"     "ASTonset"     "ALPonset"     "GGTonset"     "TBILonset"   
## [16] "ALB"          "TBA"          "Cr"           "INR"          "Timetoevents"
## [21] "Death28d"     "Death90d"     "Death6m"      "riskscore"    "riskgroup"   
## [26] "LP"           "lntbil"       "lninr"        "crmgdl"       "lncr"        
## [31] "meld"         "riskgroupRB"  "riskgroupnhl"
fit <- survfit(Surv(Timetoevents, outcome) ~ riskgroup, data = Newmodelcoxx)
               ##The risk groups were stratified according to the previously established linear formula: LP = 0.05 × TBIL(onset) [mg/dL] - 0.11 × albumin [g/L] + 0.45 × INR + 3.22. Using a cutoff value of 1.05, patients with LP > 1.05 were classified into the high-risk group, while those with LP ≤ 1.05 were assigned to the low-risk group.
ggsurvplot(fit,
           data = Newmodelcoxx,
           xlim = c(0, 180), 
           break.time.by = 30,   # One mark every 30 days, the duration can be adjusted to 100 days if the follow-up period is extended.
           # Change legends: title & labels
           legend.title = "Testing set", 
           legend.labs = c("High", "Low"),
           palette =  c("#C72228", "#0C4E9B"),
           # Add p-value and tervals
           pval = TRUE, 
           conf.int = TRUE,
           pval.size = 3,  # Reduce the font size of the p-value
           pval.coord = c(50, 0.25),  # Adjust the position of the P-value
           # Add risk table
           risk.table = TRUE, 
           tables.height = 0.25,
           risk.table.col = "strata",   
           risk.table.y.text = TRUE,    
           risk.table.y.text.col = TRUE,  
           risk.table.height = 0.25,
           risk.table.fontsize = 3     
           ,
           ncensor.plot = TRUE, 
           ncensor.plot.height = 0.2,
           font.ncensor = 8,     
           # Risk Table Theme Settings
           tables.theme = theme(
             text = element_text(size = 4), # Further reduce the font size of the risk table
             axis.title = element_text(size = 6),
             axis.text = element_text(size = 6),
             legend.position = "none" ,           
             plot.margin = unit(c(0.1, 0.1, 0.1, 0.1), "cm")  
           ),
           xlab = "Time (days)",
           ylab = "Survival Probability",
           ggtheme = theme_bw(base_size = 8)     
)

Time-dependent roc curve

library(timeROC)
library(pROC)
## Type 'citation("pROC")' for a citation.
## 
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
## 
##     cov, smooth, var
library(survival)
roc_res <- timeROC::timeROC(
  T = Newmodelcoxx$Timetoevents,  # Timetoevents just Survival time
  delta = Newmodelcoxx$outcome,   # 1=LT/Death, 0=no LT/Death
  marker = Newmodelcoxx$riskscore,       # LP score as before
  cause = 1,
  weighting = "cox",
  times = c(31, 90, 180), # This is displayed in this manner due to constraints imposed by our verification queue.  time point should be 30, 90, 180, 270
  iid = FALSE
)
print(roc_res)
## Time-dependent-Roc curve estimated using IPCW  (n=741, without competing risks). 
##       Cases Survivors Censored AUC (%)
## t=31     18       723        0   93.68
## t=90     18       695       28   95.39
## t=180    46       686        9   94.73
## 
## Method used for estimating IPCW:cox 
## 
## Total computation time : 0.31  secs.
plot(roc_res, time = 31, col = "#C72228", lwd = 2.5,title = FALSE)
plot(roc_res, time = 90, col = "#0C4E9B", lwd = 2.5,add = TRUE)
plot(roc_res, time = 180, col = "#F1b656", lwd = 2.5,add = TRUE)
legend("bottomright", legend = c("30 days   AUC: 0.937", "90 days   AUC: 0.953", "180 days AUC: 0.947"),
       col = c("#C72228", "#0C4E9B", "#F1b656"), lty = 1, lwd = 2.5,cex = 0.8)

Calibration curves

library(rms)
## Loading required package: Hmisc
## 
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:base':
## 
##     format.pval, units
library(survival)
library(openxlsx)
dd_validation <- read.xlsx("/Users/zhangmengmeng/Desktop/Rmodel/Newmodelcoxx.xlsx", sheet = 5)
Newmodelcoxx <- dd_validation     
validation_data <- Newmodelcoxx
dd_validation_dist <- datadist(validation_data)
options(datadist = "dd_validation_dist")
fit_validation <- cph(Surv(Timetoevents, outcome) ~ LP, 
                      data = validation_data, x = TRUE, y = TRUE, surv = TRUE)
cal_validation <- calibrate(fit_validation, 
                            cmethod = 'KM', 
                            method = "boot", 
                            u = 30, # The assessment time point may be 30, 90, 180,270 days.
                            m = floor(nrow(validation_data)/3), 
                            B = 500)
## Using Cox survival estimates at  30 Days
plot(cal_validation,
     lwd=2, 
     lty=1, 
     errbar.col=c("#0C4E9B"), 
     cex.lab=1.2,cex.axis=1,cex.main=1.2,cex.sub=0.1  
)
lines(cal_validation[,c('mean.predicted',"KM")],
      type= 'b', # 连线的类型,可以是"p","b","o"
      lwd = 3, # 连线的粗细
      pch = 16, #点的形状,可以是0-20
      col = "#C72228") # 连线的颜色
box(lwd = 2) # 边框粗细
abline(0,1,lty=3,#对角线为虚线
       lwd=2,#对角线的粗细
       col="grey70"#对角线的颜色
)

DCA

library(rmda)
Newmodelcoxx$event_occurred <- ifelse(Newmodelcoxx$outcome == 1, 1, 0)
Newmodelcoxx$risk_prob <- 1 / (1 + exp(-Newmodelcoxx$LP))
dca_overall <- decision_curve(
  event_occurred ~ risk_prob,   
  data = Newmodelcoxx,          
  family = binomial,          
  thresholds = seq(0, 0.5, by = 0.01),   
  study.design = "cohort",     
  bootstraps = 100             
)
plot_decision_curve(
  dca_overall,
  curve.names = "Overall Risk Model",
  col = c("#0C4E9B"),
  lwd = 2,
  confidence.intervals = FALSE,  
  legend.position = "bottomright",
  standardize = FALSE,           
  cost.benefit.axis = FALSE,    
  xlim = c(0, 0.5)              
)

Comparative Performance with Existing Prognostic Models (AUC and DCA at Total time)

rm(list=ls()) 
library(pROC)
data <- read.xlsx("/Users/zhangmengmeng/Desktop/Rmodel/Newmodelcoxx.xlsx", sheet = 5)
Newmodelcoxx <- data
colnames(data) 
##  [1] "Number"       "outcome"      "genders"      "age"          "BMI"         
##  [6] "typeofdrugs"  "injurytype"   "latency"      "WBC"          "PLT"         
## [11] "ALTonset"     "ASTonset"     "ALPonset"     "GGTonset"     "TBILonset"   
## [16] "ALB"          "TBA"          "Cr"           "INR"          "Timetoevents"
## [21] "Death28d"     "Death90d"     "Death6m"      "riskscore"    "riskgroup"   
## [26] "LP"           "lntbil"       "lninr"        "crmgdl"       "lncr"        
## [31] "meld"         "riskgroupRB"  "riskgroupnhl"
roc1<- roc(Newmodelcoxx$outcome, Newmodelcoxx$LP)  ## LP corresponding legend new model
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc2<- roc(Newmodelcoxx$outcome, Newmodelcoxx$riskgroupnhl) ##riskgroupnhl corresponding legend nHy's Law
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc3<- roc(Newmodelcoxx$outcome, Newmodelcoxx$riskgroupRB)  ##riskgroupRB corresponding legend Robles-Diaz
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc4<- roc(Newmodelcoxx$outcome, Newmodelcoxx$meld)  ##meld corresponding legend MELD
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
plot(roc1,  col = "#C72228", lwd = 2.5,title = FALSE)
plot(roc2, col = "#0C4E9B", lwd = 2.5,add = TRUE)
plot(roc3,  col = "#F1b656", lwd = 2.5,add = TRUE)
plot(roc4,  col = "#037F77", lwd = 2.5,add = TRUE)
print(roc1)
## 
## Call:
## roc.default(response = Newmodelcoxx$outcome, predictor = Newmodelcoxx$LP)
## 
## Data: Newmodelcoxx$LP in 686 controls (Newmodelcoxx$outcome 0) < 55 cases (Newmodelcoxx$outcome 1).
## Area under the curve: 0.9195
print(roc2)
## 
## Call:
## roc.default(response = Newmodelcoxx$outcome, predictor = Newmodelcoxx$riskgroupnhl)
## 
## Data: Newmodelcoxx$riskgroupnhl in 686 controls (Newmodelcoxx$outcome 0) < 55 cases (Newmodelcoxx$outcome 1).
## Area under the curve: 0.6572
print(roc3)
## 
## Call:
## roc.default(response = Newmodelcoxx$outcome, predictor = Newmodelcoxx$riskgroupRB)
## 
## Data: Newmodelcoxx$riskgroupRB in 686 controls (Newmodelcoxx$outcome 0) < 55 cases (Newmodelcoxx$outcome 1).
## Area under the curve: 0.6121
print(roc4)
## 
## Call:
## roc.default(response = Newmodelcoxx$outcome, predictor = Newmodelcoxx$meld)
## 
## Data: Newmodelcoxx$meld in 686 controls (Newmodelcoxx$outcome 0) < 55 cases (Newmodelcoxx$outcome 1).
## Area under the curve: 0.9214
legend(x = 0.646, y = 0.29, #"bottomright"
       legend = c("new model   AUC: 0.920 ",  ##new model refers to the LP score
                  "nHy's Law    AUC: 0.657 ", ##TBIL > 2 × ULN, nR ≥ 5, where nR = (ALT – maximum value) or (AST – maximum value) / ULN divided by ALP / ULN   
                  "Robles-Diaz  AUC: 0.612 ", ##AST> 17.3×ULN and TBIL> 6.6×ULN;or AST≤17.3×ULN+AST/ALT > 1.5
                  "MELD            AUC: 0.921 " ##medl=10×[(0.957×ln (Cr))+(0.378×ln (TBIL))+(1.12×ln (INR))]+6.43
                  ),
       col = c("#C72228", "#0C4E9B", "#F1b656", "#037F77"),
       lty = 1, lwd = 2.5,cex = 0.8,
       y.intersp = 1)

delong_test <- roc.test(roc1, roc2, method = "delong")
delong_test     ##If possible,please further compare the DeLong test.
## 
##  DeLong's test for two correlated ROC curves
## 
## data:  roc1 and roc2
## Z = 7.317, p-value = 2.536e-13
## alternative hypothesis: true difference in AUC is not equal to 0
## 95 percent confidence interval:
##  0.1920571 0.3325917
## sample estimates:
## AUC of roc1 AUC of roc2 
##   0.9195070   0.6571826
##DCA(Following on from the above)
library(rmda)
dca_newmodel  <- decision_curve(outcome ~ LP, data = Newmodelcoxx, family = binomial)
dca_nHysLaw <- decision_curve(outcome ~ riskgroupnhl, data = Newmodelcoxx, family = binomial)
dca_RB  <- decision_curve(outcome ~ riskgroupRB, data = Newmodelcoxx, family = binomial)
dca_meld  <- decision_curve(outcome ~ meld, data = Newmodelcoxx, family = binomial)
plot_decision_curve(
  list(dca_newmodel, dca_nHysLaw, dca_RB, dca_meld), 
  curve.names = c("newmodel","nHy's Law","Robles-Diaz","MELD"),
  col = c("#C72228", "#0C4E9B", "#F1b656","#037F77"),
  lty = c(1,1,1,1), 
  lwd = c(3,3,3,3),
  confidence.intervals = FALSE,  
  legend.position = "none",
  standardize = FALSE,
  cost.benefit.axis = FALSE
)
## Note: When multiple decision curves are plotted, decision curves for 'All' are calculated using the prevalence from the first DecisionCurve object in the list provided.
legend("bottomright",
       legend = c("newmodel","nHy's Law","Robles-Diaz","MELD"),
       col = c("#C72228", "#0C4E9B", "#F1b656", "#037F77"),
       lty = 1, 
       lwd = 3,
       cex = 0.8)  

Comparative Performance with Existing Prognostic Models( AUC and DCA at 30 days )

rm(list=ls()) 
library(pROC)
data <- read.xlsx("/Users/zhangmengmeng/Desktop/Rmodel/Newmodelcoxx.xlsx", sheet = 5)
Newmodelcoxx <- data
colnames(data) 
##  [1] "Number"       "outcome"      "genders"      "age"          "BMI"         
##  [6] "typeofdrugs"  "injurytype"   "latency"      "WBC"          "PLT"         
## [11] "ALTonset"     "ASTonset"     "ALPonset"     "GGTonset"     "TBILonset"   
## [16] "ALB"          "TBA"          "Cr"           "INR"          "Timetoevents"
## [21] "Death28d"     "Death90d"     "Death6m"      "riskscore"    "riskgroup"   
## [26] "LP"           "lntbil"       "lninr"        "crmgdl"       "lncr"        
## [31] "meld"         "riskgroupRB"  "riskgroupnhl"
roc1<- roc(Newmodelcoxx$Death28d, Newmodelcoxx$LP)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc2<- roc(Newmodelcoxx$Death28d, Newmodelcoxx$riskgroupnhl)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc3<- roc(Newmodelcoxx$Death28d, Newmodelcoxx$riskgroupRB)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
roc4<- roc(Newmodelcoxx$Death28d, Newmodelcoxx$meld) 
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
plot(roc1,  col = "#C72228", lwd = 2.5,title = FALSE)
plot(roc2, col = "#0C4E9B", lwd = 2.5,add = TRUE)
plot(roc3,  col = "#F1b656", lwd = 2.5,add = TRUE)
plot(roc4,  col = "#037F77", lwd = 2.5,add = TRUE)
print(roc1)
## 
## Call:
## roc.default(response = Newmodelcoxx$Death28d, predictor = Newmodelcoxx$LP)
## 
## Data: Newmodelcoxx$LP in 723 controls (Newmodelcoxx$Death28d 0) < 18 cases (Newmodelcoxx$Death28d 1).
## Area under the curve: 0.9368
print(roc2)
## 
## Call:
## roc.default(response = Newmodelcoxx$Death28d, predictor = Newmodelcoxx$riskgroupnhl)
## 
## Data: Newmodelcoxx$riskgroupnhl in 723 controls (Newmodelcoxx$Death28d 0) < 18 cases (Newmodelcoxx$Death28d 1).
## Area under the curve: 0.645
print(roc3)
## 
## Call:
## roc.default(response = Newmodelcoxx$Death28d, predictor = Newmodelcoxx$riskgroupRB)
## 
## Data: Newmodelcoxx$riskgroupRB in 723 controls (Newmodelcoxx$Death28d 0) < 18 cases (Newmodelcoxx$Death28d 1).
## Area under the curve: 0.595
print(roc4)
## 
## Call:
## roc.default(response = Newmodelcoxx$Death28d, predictor = Newmodelcoxx$meld)
## 
## Data: Newmodelcoxx$meld in 723 controls (Newmodelcoxx$Death28d 0) < 18 cases (Newmodelcoxx$Death28d 1).
## Area under the curve: 0.9358
legend(x = 0.75, y = 0.35, #"bottomright"
       legend = c("new model      AUC: 0.937 ", 
                  "nHy's Law      AUC: 0.645 ",
                  "Robles-Diaz  AUC: 0.595 ",
                  "MELD             AUC: 0.936 "),
       col = c("#C72228", "#0C4E9B", "#F1b656", "#037F77"),
       lty = 1, lwd = 2.5,cex = 0.8,
       y.intersp = 1)

delong_test1 <- roc.test(roc1, roc2, method = "delong")
delong_test2 <- roc.test(roc1, roc3, method = "delong")
delong_test3 <- roc.test(roc1, roc4, method = "delong")
delong_results <- data.frame(
  Comparison = c("roc1 vs roc2", "roc1 vs roc3", "roc1 vs roc4"),
  Statistic = c(delong_test1$statistic, delong_test2$statistic, delong_test3$statistic),
  P_Value = c(delong_test1$p.value, delong_test2$p.value, delong_test3$p.value),
  Method = c(delong_test1$method, delong_test2$method, delong_test3$method)
)
delong_results$Significance <- ifelse(delong_results$P_Value < 0.001, "***",
                                      ifelse(delong_results$P_Value < 0.01, "**",
                                             ifelse(delong_results$P_Value < 0.05, "*", "ns")))
print(delong_results)
##     Comparison Statistic      P_Value
## 1 roc1 vs roc2 4.8454318 1.263366e-06
## 2 roc1 vs roc3 6.9616729 3.362556e-12
## 3 roc1 vs roc4 0.0657481 9.475784e-01
##                                        Method Significance
## 1 DeLong's test for two correlated ROC curves          ***
## 2 DeLong's test for two correlated ROC curves          ***
## 3 DeLong's test for two correlated ROC curves           ns
#DCA
library(rmda)
dca_newmodel  <- decision_curve(Death28d ~ LP, data = Newmodelcoxx, family = binomial)
dca_nHysLaw <- decision_curve(Death28d ~ riskgroupnhl, data = Newmodelcoxx, family = binomial)
dca_RB  <- decision_curve(Death28d ~ riskgroupRB, data = Newmodelcoxx, family = binomial)
dca_meld  <- decision_curve(Death28d ~ meld, data = Newmodelcoxx, family = binomial)
plot_decision_curve(
  list(dca_newmodel, dca_nHysLaw, dca_RB, dca_meld), 
  curve.names = c("newmodel","nHy's Law","Robles-Diaz","MELD"),
  col = c("#C72228", "#0C4E9B", "#F1b656","#037F77"),
  lty = c(1,1,1,1), 
  lwd = c(3,3,3,3),
  confidence.intervals = FALSE,  
  legend.position = "none",
  standardize = FALSE,
  cost.benefit.axis = FALSE
)
## Note: When multiple decision curves are plotted, decision curves for 'All' are calculated using the prevalence from the first DecisionCurve object in the list provided.
legend("bottomright",
       legend = c("newmodel","nHy's Law","Robles-Diaz","MELD"),
       col = c("#C72228", "#0C4E9B", "#F1b656", "#037F77"),
       lty = 1, 
       lwd = 3,
       cex = 0.8)