Как показать событие произошло между двумя датами в 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.) Как я могу передать общий End.date
в финал drug.end
для каждого ID
?
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
Любая помощь приветствуется.
3 ответа
Ты можешь попробовать
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". Если вам это нужно в формате "символ", просто раскомментируйте последнюю строку и запустите ее.
ПРИМЕЧАНИЕ. Удалено group_by
как это было не нужно
Ее возможно 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]
Ответа Акруна достаточно для решения проблемы. Предлагая более простой код.
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))