R время жизни зависит от ковариата выходного дня: как разделить
Я смотрю на влияние, которое выходные могут оказать на выживание человека, и поэтому я пытаюсь преобразовать свои данные в зависящую от времени структуру с одной строкой за интервал. Вероятно, это будет модель Кокса с датой DschDT (Дата выписки) в качестве даты цензуры. Либо пациент выписывается живым (с цензурой справа), либо умирает в больнице.
Данные выглядят так, где DIH - моя переменная цензуры (0,1)
`structure(list(Age = c(28L, 77L, 92L, 28L, 59L, 7L), Sex = structure(c(1L,
2L, 1L, 1L, 2L, 2L), .Label = c("F", "M"), class = "factor"),
Care.type = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Acute",
"Organ.Procurement", "Geriatric.Eval.Mgt", "Psychogeriatric",
"Maintenance", "Rehab", "Palliative"), class = "factor"),
AdmDT = structure(c(1396282680, 1396311600, 1396329780, 1396331040,
1396343940, 1396348080), class = c("POSIXct", "POSIXt"), tzone = ""),
DschgDT = structure(c(1396288800, 1396335600, 1397721600,
1396338600, 1396390200, 1396359120), class = c("POSIXct",
"POSIXt"), tzone = ""), DIH = c(0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("Age",
"Sex", "Care.type", "AdmDT", "DschgDT", "DIH"), row.names = c(1L,
7L, 8L, 9L, 10L, 11L), class = "data.frame")`
Например, у меня может быть пациент, которого госпитализируют в среду и выписывают живым в следующий четверг. В этом случае будет три ряда для этого эпизода пациентов. Один для среды-пятницы, один для субботы-воскресенья и один для понедельника-четверга, все включено.
Мне удалось определить выходные в течение определенного периода времени, используя эту функцию.
getDuration <- function(d1, d2,fmt="%Y-%m-%d %H%M") {
myDays <- seq.Date(to = as.Date(d2, format=fmt),
from = as.Date(d1, format =fmt),
by = 1)
myDays[which(is.weekend(myDays))]
}
dat<-mapply(getDuration,AdmDT,DschgDT)
> head(clip)
ID StartDate EndDate Start Time Event WeekendStart1 WeekendEnd1 WeekendStart2 WeekendEnd2
1 1 9/08/2013 16/08/2013 0 7 0 1 3 0 0
2 2 9/12/2013 12/12/2013 0 3 0 0 0 0 0
3 3 9/01/2014 17/01/2014 0 8 1 2 4 0 0
После определения места проведения выходных между датами я хотел бы разделить время по выходным. Для этого примера результирующие данные будут выглядеть так:
clip2
ID StartDate EndDate Start Time Event Weekend
1 1 9/08/2013 16/08/2013 0 1 0 0
2 1 9/08/2013 16/08/2013 1 3 0 1
3 1 9/08/2013 16/08/2013 3 7 0 0
4 2 9/12/2013 12/12/2013 0 3 0 0
5 3 9/01/2014 17/01/2014 0 2 0 0
6 3 9/01/2014 17/01/2014 2 4 0 1
7 3 9/01/2014 17/01/2014 4 8 1 0
Однако я не могу найти способ разделить временные интервалы эффективным способом, survSplit
а также tmerge
от survival
пакет, кажется, не имеет функциональности для этого. Кто-нибудь может дать мне некоторые идеи, кроме как провести большой уродливый цикл?
Обновить. Ну, мне удалось сделать это после большого количества царапин на голове. Для тех, кому интересно. Эта функция находит то, что больница считает выходным днем, т.е. начинается в пятницу вечером и заканчивается рано утром в понедельник. Конечно, вы можете редактировать, чтобы удовлетворить. Эта функция возвращает пятницу и воскресенье, так что вы можете разделить в эти дни.
is.weekend<-function (x)
{
library(chron)
if (!inherits(x, "dates"))
x<-as.chron(as.character(x))
v <- month.day.year(x)
h<-hours(x)
out <- day.of.week(v$month, v$day, v$year) + 1
# 1 is Sunday and 7 is Saturday, h is hours
x<-((out == 6 & h >= 18) | out==7|out==1|(out == 2 & h < 6))
return(x)
}
Это более простая версия выше, чтобы получить интервалы
Основная функция для определения количества выходных, начиная с субботы и заканчивая в воскресенье. d1 и d2 - дата / время приема и выписки соответственно.
getDuration <- function(d1, d2) {
myDays <- seq(d1,d2,by="hour")
myDays[which(is.weekend(myDays))]
}
Эта функция делает временную последовательность для каждой записи
survSeq.dh<-function(a,w){
aa<-sort(c(a,as.POSIXct(w)))
aa<-diff(aa)
units(aa)<-"hours"
aa<-as.numeric(aa)
aa<-cumsum(aa)
#Identify the start and end of weekends
aa1<-which(diff(aa)!=1)
aa1<-sort(c(aa1,aa1+1))
aa1<-c(aa[1],aa[aa1],aa[length(aa)])/24
}
Немного уборки
#Make a survSplit object
#Create a start and stop time
dat$start<-0
dat$time<-as.numeric(dat$separation_datetime-dat$admission_datetime)/(60*24)
Event variable
dat$DIH<-dat$mode_of_separation=="Died in hospital"
Последняя версия Survival:: Survious создает объект Surv, что значительно замедляет процесс, поэтому я использую старую версию.
Новая функция SurvSplit в пакете для выживания 2.39-2 работает слишком медленно.
survSplit2<-function (data, cut, end, event, start, id = NULL, zero = 0,
episode = NULL)
{
cut <- sort(cut)
ntimes <- length(cut)
n <- nrow(data)
newdata <- lapply(data, rep, ntimes + 1)
endtime <- rep(c(cut, Inf), each = n)
eventtime <- newdata[[end]]
if (start %in% names(data))
starttime <- data[[start]]
else starttime <- rep(zero, length.out = n)
starttime <- c(starttime, pmax(starttime, rep(cut, each = n)))
epi <- rep(0:ntimes, each = n)
status <- ifelse(eventtime <= endtime & eventtime > starttime,
newdata[[event]], 0)
endtime <- pmin(endtime, eventtime)
drop <- starttime >= endtime
newdata <- do.call("data.frame", newdata)
newdata[, start] <- starttime
newdata[, end] <- endtime
newdata[, event] <- status
if (!is.null(id))
newdata[, id] <- rep(rownames(data), ntimes + 1)
if (!is.null(episode))
newdata[, episode] <- epi
newdata <- newdata[!drop, ]
newdata
}
Затем запустите скрипт
Найти выходные / нерабочие часы для каждой записи пациента
xx.s<-mapply(getDuration,dat$admission_datetime,dat$separation_datetime))
Определите время начала и окончания каждого выходного дня
xx.surv<-mapply(survSeq,dat$admission_datetime,xx.s)
Поместите много в петлю (извините)
lengthx<-dim(dat)[1]
dat.l<-list()
for(i in 1:lengthx){
print(i)
dat.l[[i]]<-survSplit2(dat[i,],cut=xx.surv[[i]],end="time",start="start",event="DIH")
}
library(data.table)
dat.l<-data.frame(rbindlist(dat.l))
Так что теперь у меня есть основа способа разработки модели, зависящей от времени, которая позволяет больничному отделению человека переключаться между опасными функциями, поскольку его пребывание чередуется между выходными и днем недели.
например, coxph(Surv(начало, время,DIH)~DayOfWeek)