我正在研究周末可能对个人生存的影响,因此我试图将我的数据转换为时间相关的结构,每个间隔一行。它可能是一个以 DschDT(出院日期)作为审查日期的 Cox PH 模型。患者要么活着出院(右删失),要么在医院内死亡。
数据看起来像这样,其中 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"
最新版本的生存::survSplit 创建了一个 Surv 对象,这大大减慢了进程,所以我使用旧版本。
生存包 2.39-2 中的新 survSplit 功能太慢。
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(start,time,DIH)~DayOfWeek)