如何显示R中两个日期之间发生的事件
how to show an event happened between two dates in R
我的问题看起来很简单,但愿如此。
我有一个数据框,其中包含疾病的诊断日期、指示患者服用哪种药物(或暴露组和未暴露组)的二进制变量、药物的开始和停止日期以及整体停止日期。
ID Diag_date Treatment End.date Drug.start drug.end
1 NA 0 15/03/2002 01/01/2002 01/02/2002
1 NA 1 15/03/2002 01/02/2002 01/03/2002
1 NA 0 15/03/2002 01/03/2002 NA
2 01/04/2002 1 01/05/2002 01/01/2015 01/02/2002
2 01/04/2002 0 01/05/2002 01/02/2002 01/03/2002
2 01/04/2002 0 01/05/2002 01/03/2002 NA
如您所见,诊断日期不随时间变化,但药物开始和停止日期随时间变化。
最好我想回答两个问题:
1.) 我如何将每个 ID
的总 End.date
转换为最终 drug.end
?
2.) 如何创建一个二进制列来显示诊断日期是否出现在 Drug.start
和 Drug.end
之间?
我希望我的最终数据如下所示:
ID Diag_date Treatment End.Date Drug.start Drug.end Event
1 NA 0 15/03/2002 01/01/2002 01/02/2002 0
1 NA 1 15/03/2002 01/02/2002 01/03/2002 0
1 NA 0 15/03/2002 01/03/2002 15/03/2002 0
2 01/04/2002 1 01/05/2002 01/01/2015 01/02/2002 0
2 01/04/2002 0 01/05/2002 01/02/2002 01/03/2002 0
2 01/04/2002 0 01/05/2002 01/03/2002 01/05/2002 1
并非每个人都有诊断日期,因为并非样本中的每个人都患有这种疾病。我写的代码如下:
for (i in 1:nrow(df)) {
if ((df$Diag_date[i] >= df$Drug.start[i]) && ( df$Diag_date[i] <= df$Drug.stop[i])) {
df$Event[i] <- 1
} else {
df$Event[i] <- 0
}
}
我在 运行 此代码时得到的错误是:
missing value where TRUE/FALSE needed
如有任何帮助,我们将不胜感激。
你可以试试
library(dplyr)
df1 %>%
mutate_each(funs(as.Date(., '%d/%m/%Y')), matches('start|end|date')) %>%
mutate(drug.end= as.Date(ifelse(is.na(drug.end), End.date,
drug.end),origin='1970-01-01'),
Event= as.integer((Diag_date >= Drug.start & Diag_date<=drug.end) &
!is.na(Diag_date))) #%>%
#mutate_each(funs(format(., '%d/%m/%Y')), matches('start|end|date'))
# ID Diag_date Treatment End.date Drug.start drug.end Event
#1 1 <NA> 0 2002-03-15 2002-01-01 2002-02-01 0
#2 1 <NA> 1 2002-03-15 2002-02-01 2002-03-01 0
#3 1 <NA> 0 2002-03-15 2002-03-01 2002-03-15 0
#4 2 2002-04-01 1 2002-05-01 2015-01-01 2002-02-01 0
#5 2 2002-04-01 0 2002-05-01 2002-02-01 2002-03-01 0
#6 2 2002-04-01 0 2002-05-01 2002-03-01 2002-05-01 1
正如@David Arenburg 提到的,最好将 'date' 列保留为 'Date' class。如果您需要 'character' 格式,只需取消注释最后一行并 运行 它。
注意:删除了 group_by
,因为不需要
Akrun 的回答足以解决手头的问题。建议更直接的代码。
A <- read.table("clipboard", header = T)
Dates <- c("Diag_date", "End.date", "Drug.start", "drug.end")
A[,Dates] <- lapply(A[,Dates],function(x) as.Date(x, format = "%d/%m/%Y"))
A$drug.end[is.na(A$drug.end)] <- as.character(A$End.date[is.na(A$drug.end)])
A$Event <- as.numeric((A$Diag_date >= A$Drug.start & A$Diag_date<=A$drug.end) & !is.na(A$Diag_date))
她可能 data.table
相当
library(data.table)
# Converting to dates
Dates <- names(df)[c(2, 4:6)]
setDT(df)[, (Dates) := lapply(.SD, as.IDate, format = "%d/%m/%Y"), .SDcols = Dates]
# First question
df[is.na(drug.end), drug.end := End.date]
# Second question
df[Diag_date >= Drug.start & Diag_date <= drug.end, Event := 1L]
我的问题看起来很简单,但愿如此。
我有一个数据框,其中包含疾病的诊断日期、指示患者服用哪种药物(或暴露组和未暴露组)的二进制变量、药物的开始和停止日期以及整体停止日期。
ID Diag_date Treatment End.date Drug.start drug.end
1 NA 0 15/03/2002 01/01/2002 01/02/2002
1 NA 1 15/03/2002 01/02/2002 01/03/2002
1 NA 0 15/03/2002 01/03/2002 NA
2 01/04/2002 1 01/05/2002 01/01/2015 01/02/2002
2 01/04/2002 0 01/05/2002 01/02/2002 01/03/2002
2 01/04/2002 0 01/05/2002 01/03/2002 NA
如您所见,诊断日期不随时间变化,但药物开始和停止日期随时间变化。
最好我想回答两个问题:
1.) 我如何将每个 ID
的总 End.date
转换为最终 drug.end
?
2.) 如何创建一个二进制列来显示诊断日期是否出现在 Drug.start
和 Drug.end
之间?
我希望我的最终数据如下所示:
ID Diag_date Treatment End.Date Drug.start Drug.end Event
1 NA 0 15/03/2002 01/01/2002 01/02/2002 0
1 NA 1 15/03/2002 01/02/2002 01/03/2002 0
1 NA 0 15/03/2002 01/03/2002 15/03/2002 0
2 01/04/2002 1 01/05/2002 01/01/2015 01/02/2002 0
2 01/04/2002 0 01/05/2002 01/02/2002 01/03/2002 0
2 01/04/2002 0 01/05/2002 01/03/2002 01/05/2002 1
并非每个人都有诊断日期,因为并非样本中的每个人都患有这种疾病。我写的代码如下:
for (i in 1:nrow(df)) {
if ((df$Diag_date[i] >= df$Drug.start[i]) && ( df$Diag_date[i] <= df$Drug.stop[i])) {
df$Event[i] <- 1
} else {
df$Event[i] <- 0
}
}
我在 运行 此代码时得到的错误是:
missing value where TRUE/FALSE needed
如有任何帮助,我们将不胜感激。
你可以试试
library(dplyr)
df1 %>%
mutate_each(funs(as.Date(., '%d/%m/%Y')), matches('start|end|date')) %>%
mutate(drug.end= as.Date(ifelse(is.na(drug.end), End.date,
drug.end),origin='1970-01-01'),
Event= as.integer((Diag_date >= Drug.start & Diag_date<=drug.end) &
!is.na(Diag_date))) #%>%
#mutate_each(funs(format(., '%d/%m/%Y')), matches('start|end|date'))
# ID Diag_date Treatment End.date Drug.start drug.end Event
#1 1 <NA> 0 2002-03-15 2002-01-01 2002-02-01 0
#2 1 <NA> 1 2002-03-15 2002-02-01 2002-03-01 0
#3 1 <NA> 0 2002-03-15 2002-03-01 2002-03-15 0
#4 2 2002-04-01 1 2002-05-01 2015-01-01 2002-02-01 0
#5 2 2002-04-01 0 2002-05-01 2002-02-01 2002-03-01 0
#6 2 2002-04-01 0 2002-05-01 2002-03-01 2002-05-01 1
正如@David Arenburg 提到的,最好将 'date' 列保留为 'Date' class。如果您需要 'character' 格式,只需取消注释最后一行并 运行 它。
注意:删除了 group_by
,因为不需要
Akrun 的回答足以解决手头的问题。建议更直接的代码。
A <- read.table("clipboard", header = T)
Dates <- c("Diag_date", "End.date", "Drug.start", "drug.end")
A[,Dates] <- lapply(A[,Dates],function(x) as.Date(x, format = "%d/%m/%Y"))
A$drug.end[is.na(A$drug.end)] <- as.character(A$End.date[is.na(A$drug.end)])
A$Event <- as.numeric((A$Diag_date >= A$Drug.start & A$Diag_date<=A$drug.end) & !is.na(A$Diag_date))
她可能 data.table
相当
library(data.table)
# Converting to dates
Dates <- names(df)[c(2, 4:6)]
setDT(df)[, (Dates) := lapply(.SD, as.IDate, format = "%d/%m/%Y"), .SDcols = Dates]
# First question
df[is.na(drug.end), drug.end := End.date]
# Second question
df[Diag_date >= Drug.start & Diag_date <= drug.end, Event := 1L]