Поведение tcut с pyears при использовании времени запуска / остановки вместо времени наблюдения - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь использовать 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?

спасибо, Питер

1 Ответ

0 голосов
/ 12 марта 2020

Моя цель правильно составить таблицу возраста - это указать возраст в начале интервала, а не возраст на дату (с некоторым предварительным зачислением), как показано здесь:

# 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

сокращение «возраста». int ', кажется, дает желаемое поведение. Я также (я думаю) включил рекомендацию @AllanCameron просто сохранить объект в data.frame.

...