Likelihood ratio tests with the survstan package

library(survstan)
#> Loading required package: survival
library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(GGally)
#> Registered S3 method overwritten by 'GGally':
#>   method from   
#>   +.gg   ggplot2

Ipass data

data(ipass)
glimpse(ipass)
#> Rows: 1,217
#> Columns: 3
#> $ time   <dbl> 0.102703, 0.102703, 0.102703, 0.205483, 0.376758, 0.376758, 0.3…
#> $ status <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
#> $ arm    <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …

ipass <- ipass %>%
  mutate(
    arm = as.factor(ipass$arm), 
    arm = ifelse(arm == 1, "gefitinib", "carboplatin/paclitaxel")
  )

km <- survfit(Surv(time, status) ~ arm, data = ipass)
p <- ggsurv(km) 
p

ph <- phreg(Surv(time, status)~arm, data=ipass, baseline = "weibull")
po <- poreg(Surv(time, status)~arm, data=ipass, baseline = "weibull")
yp <- ypreg(Surv(time, status)~arm, data=ipass, baseline = "weibull")


anova(ph, yp)
#> 
#> weibull(ph) 1: Surv(time, status) ~ arm 
#> weibull(yp) 2: Surv(time, status) ~ arm 
#> --- 
#>                  loglik       LR df  Pr(>Chi)    
#> weibull(ph) 1: -2839.24   133.72  1 < 2.2e-16 ***
#> weibull(yp) 2: -2772.38        -  -         -    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(po, yp)
#> 
#> weibull(po) 1: Surv(time, status) ~ arm 
#> weibull(yp) 2: Surv(time, status) ~ arm 
#> --- 
#>                  loglik       LR df  Pr(>Chi)    
#> weibull(po) 1: -2851.32   157.89  1 < 2.2e-16 ***
#> weibull(yp) 2: -2772.38        -  -         -    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

AIC(ph, po, yp)
#>   fit      aic npars
#> 1  yp 5552.751     4
#> 2  ph 5684.475     3
#> 3  po 5708.640     3

Veteran data

glimpse(veteran)
#> Rows: 137
#> Columns: 8
#> $ trt      <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
#> $ celltype <fct> squamous, squamous, squamous, squamous, squamous, squamous, s…
#> $ time     <dbl> 72, 411, 228, 126, 118, 10, 82, 110, 314, 100, 42, 8, 144, 25…
#> $ status   <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0…
#> $ karno    <dbl> 60, 70, 60, 60, 70, 20, 40, 80, 50, 70, 60, 40, 30, 80, 70, 6…
#> $ diagtime <dbl> 7, 5, 3, 9, 11, 5, 10, 29, 18, 6, 4, 58, 4, 9, 11, 3, 9, 2, 4…
#> $ age      <dbl> 69, 64, 38, 63, 65, 49, 69, 68, 43, 70, 81, 63, 63, 52, 48, 6…
#> $ prior    <dbl> 0, 10, 0, 10, 10, 0, 10, 0, 0, 0, 0, 10, 0, 10, 10, 0, 0, 0, …

veteran <- veteran %>%
  mutate(across(c(trt, celltype), as.factor))

dist <- "loglogistic"
formula <- Surv(time, status) ~ celltype + trt + karno

cox <- coxph(
  formula = formula,
  data=veteran
)

cox.zph(cox)
#>           chisq df       p
#> celltype 14.532  3 0.00226
#> trt       0.206  1 0.64968
#> karno    12.813  1 0.00034
#> GLOBAL   22.860  5 0.00036

yp <- ypreg(
  formula = formula,
  data = veteran, dist = dist
)

ph <- phreg(
  formula = formula,
  data = veteran, dist = dist
)

po <- poreg(
  formula = formula,
  data = veteran, dist = dist
)

anova(ph, yp)
#> 
#> loglogistic(ph) 1: Surv(time, status) ~ celltype + trt + karno 
#> loglogistic(yp) 2: Surv(time, status) ~ celltype + trt + karno 
#> --- 
#>                      loglik       LR df Pr(>Chi)    
#> loglogistic(ph) 1: -730.403   45.045  5 1.42e-08 ***
#> loglogistic(yp) 2: -707.880        -  -        -    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(po, yp)
#> 
#> loglogistic(po) 1: Surv(time, status) ~ celltype + trt + karno 
#> loglogistic(yp) 2: Surv(time, status) ~ celltype + trt + karno 
#> --- 
#>                       loglik        LR df Pr(>Chi)  
#> loglogistic(po) 1: -712.5483    9.3361  5  0.09639 .
#> loglogistic(yp) 2: -707.8803         -  -        -  
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1


logLik(ph, po, yp)
#>   fit    loglik npars
#> 1  yp -707.8803    12
#> 2  po -712.5483     7
#> 3  ph -730.4029     7
AIC(ph, po, yp)
#>   fit      aic npars
#> 1  po 1439.097     7
#> 2  yp 1439.761    12
#> 3  ph 1474.806     7