简体   繁体   中英

Stratified log-rank test in R for counting process form data?

Background : at half-year follow up times for 4y, patients may switch to a different medication group. To account for this, I've converted survival data into counting process form. I want to compare survival curves for medication groups A, B, and C. I am using an extended Cox model but want to do pairwise comparisons of each hazard function or do stratified log-rank tests. pairwise_survdiff throws an error because of the form of my data, I think.

Example data :

x<-data.frame(tstart=rep(seq(0,18,6),3),tstop=rep(seq(6,24,6),3), rx = rep(c("A","B","C"),4), death=c(rep(0,11),1))
x

Problem :

When using survdiff in the survival package,

survdiff(Surv(tstart,tstop,death) ~ rx, data = x)

I get the error:

Error in survdiff(Surv(tstart, tstop, death) ~ rx, data = x) : 
  Right censored data only

I think this stems from the counting process form, since I can't find an example online that compares survival curves for time-varying covariates.

Question : is there a quick fix to this problem? Or, is there an alternative package/function with the same versatility to compare survival curves, namely using different methods? How can I implement stratified log-rank tests using survidff on counting process form data?

NOTE : this was marked as a known issue in the survminer package, see github issue here, but updating survminer did not solve my issue, and using one time interval, tstop-tstart wouldn't be correct, since that would leave, eg, multiple entries at 6 months rather than out to the actual interval of risk.

So, here is an example of fitting the model and making the multiple comparisons using multcomp package. Note that this implicitly assumes that administration of treatments AC is random. Depending on the assumptions about the process, it might be better to fit a multistate model with transitions between treatments and outcome.

library(purrr)
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(survival)
library(multcomp)
#> Loading required package: mvtnorm
#> Loading required package: TH.data
#> Loading required package: MASS
#> 
#> Attaching package: 'MASS'
#> The following object is masked from 'package:dplyr':
#> 
#>     select
#> 
#> Attaching package: 'TH.data'
#> The following object is masked from 'package:MASS':
#> 
#>     geyser
# simulate survival data
set.seed(123)
n <- 200
df <- data.frame(
  id = rep(1:n, each = 8),
  start = rep(seq(0, 42, by = 6), times = 8),
  stop = rep(seq(6, 48, by = 6), times = 8),
  rx = sample(LETTERS[1:3], n * 8, replace = T))
df$hazard <- exp(-3.5  -1 * (df$rx == "A") + .5 * (df$rx == "B") +
  .5 * (df$rx == "C"))

df_surv <- data.frame(id = 1:n)
df_surv$time <- split(df, f = df$id) %>%
  map_dbl(~msm::rpexp(n = 1, rate = .x$hazard, t = .x$start))

df <- df %>% left_join(df_surv)
#> Joining, by = "id"
df <- df %>%
  mutate(status = 1L * (time <= stop)) %>%
  filter(start <= time)
df %>% head()
#>   id start stop rx     hazard     time status
#> 1  1     0    6  A 0.01110900 13.78217      0
#> 2  1     6   12  C 0.04978707 13.78217      0
#> 3  1    12   18  B 0.04978707 13.78217      1
#> 4  2     0    6  B 0.04978707 22.37251      0
#> 5  2     6   12  B 0.04978707 22.37251      0
#> 6  2    12   18  C 0.04978707 22.37251      0

# fit the model 
model <- coxph(Surv(start, stop, status)~rx, data = df)

# define pairwise comparison
glht_rx <- multcomp::glht(model, linfct=multcomp::mcp(rx="Tukey"))
glht_rx
#> 
#>   General Linear Hypotheses
#> 
#> Multiple Comparisons of Means: Tukey Contrasts
#> 
#> 
#> Linear Hypotheses:
#>            Estimate
#> B - A == 0  1.68722
#> C - A == 0  1.60902
#> C - B == 0 -0.07819

# perform multiple comparisons 
# (adjusts for multiple comparisons + takes into account correlation of coefficients -> more power than e.g. bonferroni)
smry_rx <- summary(glht_rx)
smry_rx # -> B and C different to A, but not from each other
#> 
#>   Simultaneous Tests for General Linear Hypotheses
#> 
#> Multiple Comparisons of Means: Tukey Contrasts
#> 
#> 
#> Fit: coxph(formula = Surv(start, stop, status) ~ rx, data = df)
#> 
#> Linear Hypotheses:
#>            Estimate Std. Error z value Pr(>|z|)    
#> B - A == 0  1.68722    0.28315   5.959   <1e-05 ***
#> C - A == 0  1.60902    0.28405   5.665   <1e-05 ***
#> C - B == 0 -0.07819    0.16509  -0.474     0.88    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> (Adjusted p values reported -- single-step method)
# confidence intervals
plot(smry_rx)

Created on 2019-04-01 by the reprex package (v0.2.1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM