【问题标题】:tcut behavior with pyears when using start/stop times instead of follow-up time使用开始/停止时间而不是后续时间时的 tcut 行为与 pyears
【发布时间】:2020-03-11 06:54:46
【问题描述】:

我正在尝试使用 pyears 来估计一个队列中的发病率,其中我感兴趣的协变量之一是事件发生时的年龄(而不是入学年龄,即入学队列)。事件的年龄当然取决于时间。执行此操作的正确方法似乎是在注册时使用 tcut,如 pyears 帮助中所示。但是,它似乎仅在开始时间始终为零时才有效(或者您使用等效的方法为 Surv 对象提供后续时间而不是开始/结束时间)。对于我的场景,使用实际的开始/结束时间很重要,因为我还想使用其他随时间变化的协变量,例如日历年。

这里有一个例子来说明问题:

library(tidyverse)
library(survival)

# encode actual start/end dates
s1 <- tibble(stime = as.numeric(as.Date("2000-01-01")) + 1:10,
             etime = stime + 365.25,
             futime = etime - stime,
             outcome = c(1,1,1,0,0,0,0,0,0,0),
             age.enr = floor(runif(10, 15, 64.999)))

# encode time elapsed from origin of zero
s2 <- tibble(stime = 0,
             etime = stime + 365.25,
             futime = etime - stime,
             outcome = c(1,1,1,0,0,0,0,0,0,0),
             age.enr = floor(runif(10, 15, 64.999)))

# these ought to give the same results, but don't (the second one appears to be right)
pyears(Surv(stime, etime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s1, scale=1)$pyears
pyears(Surv(futime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s1, scale=1)$pyears

# test it with a dataset where start time is always zero - works
pyears(Surv(stime, etime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s2, scale=1)$pyears
pyears(Surv(futime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s2, scale=1)$pyears

这会导致:

> # these ought to give the same results, but don't (the second one appears to be right)
> pyears(Surv(stime, etime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s1, scale=1)$pyears
tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale = 365.25)
 0+ thru 24 24+ thru 34 34+ thru 44 44+ thru 54 54+ thru 64 
       0.00        0.00        0.00        0.00      365.25 
> pyears(Surv(futime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s1, scale=1)$pyears
tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale = 365.25)
 0+ thru 24 24+ thru 34 34+ thru 44 44+ thru 54 54+ thru 64 
       0.00      365.25      730.50     1461.00      730.50 
> 
> # test it with a dataset where start time is always zero - works
> pyears(Surv(stime, etime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s2, scale=1)$pyears
tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale = 365.25)
 0+ thru 24 24+ thru 34 34+ thru 44 44+ thru 54 54+ thru 64 
     730.50     1095.75     1095.75      730.50        0.00 
> pyears(Surv(futime, outcome) ~ tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale=365.25), data=s2, scale=1)$pyears
tcut(age.enr, c(0, 24, 34, 44, 54, 64), scale = 365.25)
 0+ thru 24 24+ thru 34 34+ thru 44 44+ thru 54 54+ thru 64 
     730.50     1095.75     1095.75      730.50        0.00 

第一个示例在提供开始/结束时间时失败,但在提供经过时间时有效,而第二个示例在开始/结束或经过时间下都有效(因为开始时间被人为设置为零)。

我意识到这是一种解决这种情况的方法,但是无论间隔如何编码,pyears + tcut 不应该表现相同吗?我是否误解了 tcut 应该做什么?

谢谢, 彼得

【问题讨论】:

  • 我认为这与tcut 无关。问题在于 Surv 模型。当您传入开始时间和结束时间时,Surv 假定您使用的是间隔审查而不是右审查。令我困惑的是为什么您需要模型中的实际开始和结束时间。您可以将整个 Surv 对象作为数据框中的一列,并将您喜欢的任何协变量传递给模型。这样做比试图强迫 Surv 做一些不寻常的事情要容易得多,尝试从中提取协变量。
  • 实际上,除了@AllanCameron 指出的问题外,我还注意到另一个概念缺陷。由于临时向外迁移,我的跟进时间有差距,所以我用开始和结束时间对时间间隔进行编码,因为同一个人可以在时间轴上的多个时间间隔内被跟踪。但是,tcut 无法知道此示例中的注册日期,因此我真正需要运行 tcut 的是“间隔开始时的年龄”。我已将我的代码转换为使用该方法。

标签: r survival


【解决方案1】:

我正确列出年龄的目标需要指定间隔开始时的年龄,而不是(某些先前注册)日期的年龄,如下所示:

# another example, using DOB which is truly constant
set.seed(1234)
s1 <- tibble(stime = as.numeric(as.Date("2000-01-01")) + 1:10,
             etime = stime + 3652.50,
             outcome = c(1,1,1,0,0,0,0,0,0,0),
             dob = round(runif(10, as.Date("1930-01-01"), 
                               as.Date("1985-01-01"))),
             age.enr = floor((stime - dob)/365.25),
             age.end = floor((etime - dob)/365.25),
             sobj = Surv(etime - stime, outcome)) # just for convenience
summary(s1)
s1 %>% mutate_at(vars(stime, etime, dob), ~as.Date(.x, origin="1970-01-01"))

s1$enrd <- s1$stime - 365.25*3               # simulate an erolment date 3 years prior to this interval
s1$age.int <- s1$age.enr                     # actually, this is the age at beginning of interval, not enrolment
s1$age.enr <- floor((s1$enrd - s1$dob)/365.25)

pyears(sobj ~ tcut(age.enr, c(0, 25, 35, 45, 55, 65,999), scale=365.25), data=s1)$pyears # incorrect
pyears(sobj ~ tcut(age.int, c(0, 25, 35, 45, 55, 65,999), scale=365.25), data=s1)$pyears # correct

削减 'age.int' 似乎给出了期望的行为。我还(我认为)合并了@AllanCameron 的建议,将对象存储在 data.frame 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2019-01-22
    • 1970-01-01
    • 2021-04-07
    • 2019-08-24
    相关资源
    最近更新 更多