Использование SurvSplit в R для нескольких дат начала - PullRequest
0 голосов
/ 26 июня 2018

Если у меня есть набор данных

ID     DOB         STARTDATE     ENDDATE     FAILURE
1      10/10/75    5/10/84       15/5/03     0
2      15/9/76     10/3/84       19/6/92     0
2      15/9/76     22/2/93       15/1/99     0
2      15/9/76     15/4/99       15/1/03     0
  • Где ID - пациент
  • DOB - дата их рождения
  • STARTDATE - когда они поступили в исследование
  • ENDDATE - это когда они покинули кабинет
  • НЕУДАЧА, если они умерли или нет

Есть несколько дат начала для некоторых лиц

Я пытаюсь манипулировать им, чтобы у нас была и новая запись STARTDATE через 10 и 20 лет после DOB (до достижения ENDDATE). Так

ID     DOB         STARTDATE     ENDDATE     FAILURE
1      10/10/75    5/10/84       15/5/03     0
2      15/9/76     10/3/84       19/6/92     0
2      15/9/76     14/9/86       19/6/92     0
2      15/9/76     22/2/93       15/1/99     0
2      15/9/76     15/9/96       15/1/99     0
2      15/9/76     15/4/99       15/1/03     0
  • ID = 1 остается неизменным, так как разница между DOB и STARTDATE уже меньше 10
  • ID = 2 сохраняет три текущие строки и добавляет две новые строки. Один 10 лет после DOB и один 20 лет после DOB

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

library(eeptools)
AGEENTRY <- age_calc(DOB, STARTDATE, units = "years")

А потом запустить survSplit как так

survSplit(DATA, cut = c(10, 20), end = "AGEENTRY", 
                        event = "FAILURE", start = "START")

Я знаю, что в STATA это может быть сделано довольно хорошо с stsplit newvariable, at(10(10)20)

Однако, это не совсем то, что я надеялся. Я застрял над этой проблемой уже более суток, поэтому любая помощь будет очень признательна!

1 Ответ

0 голосов
/ 27 июня 2018

Один из подходов может быть

library(tidyverse)
library(lubridate)
library(anytime)

#convert character columns of sample data to date columns    
df <- df %>% 
  mutate_if(grepl("/", .), ~ as.Date(., format = "%d/%m/%Y")) 

#identify STARTDATE + 10 (20, 30 ...) years and then process data to have the desired result
df %>%
  group_by(ID, DOB) %>%
  mutate(temp = paste(seq.Date(unique(DOB), max(STARTDATE), by = "10 year")[-1], collapse = ',')) %>%
  separate_rows(temp, sep = ',') %>%
  group_by(STARTDATE, add = T) %>%
  filter(anydate(temp) == min(anydate(temp)[anydate(temp) > STARTDATE])) %>%
  ungroup() %>%   #STARTDATE + 10 (20, 30 ...) years are identified here
  right_join(df) %>%
  mutate(STARTDATE = ifelse(!is.na(temp), paste(STARTDATE, temp, sep = ','), as.character(STARTDATE))) %>%
  separate_rows(STARTDATE, sep = ',') %>%
  select(-temp)

, что дает

     ID DOB        STARTDATE  ENDDATE    FAILURE
1     1 1975-10-10 1984-10-05 2003-05-15       0
2     2 1976-09-15 1984-03-10 1992-06-19       0
3     2 1976-09-15 1986-09-15 1992-06-19       0
4     2 1976-09-15 1993-02-22 1999-01-15       0
5     2 1976-09-15 1996-09-15 1999-01-15       0
6     2 1976-09-15 1999-04-15 2003-01-15       0


Пример данных:

df <- structure(list(ID = c(1L, 2L, 2L, 2L), DOB = c("10/10/1975", 
"15/9/1976", "15/9/1976", "15/9/1976"), STARTDATE = c("5/10/1984", 
"10/3/1984", "22/2/1993", "15/4/1999"), ENDDATE = c("15/5/2003", 
"19/6/1992", "15/1/1999", "15/1/2003"), FAILURE = c(0L, 0L, 0L, 
0L)), .Names = c("ID", "DOB", "STARTDATE", "ENDDATE", "FAILURE"
), class = "data.frame", row.names = c(NA, -4L))

#  ID        DOB STARTDATE   ENDDATE FAILURE
#1  1 10/10/1975 5/10/1984 15/5/2003       0
#2  2  15/9/1976 10/3/1984 19/6/1992       0
#3  2  15/9/1976 22/2/1993 15/1/1999       0
#4  2  15/9/1976 15/4/1999 15/1/2003       0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...