创建一个变量,指示目标日期是否在两个日期之间,但每个案例都有几行

Creating a variable which indicates if a target date is between two dates, but there are several rows per case

提问人:Claudio Bravo 提问时间:8/25/2023 更新时间:8/27/2023 访问量:56

问:

我正在尝试创建一个名为 positive 的新变量,该变量表示targ_date介于 st_dateen_date 之间的日期范围之间,但每个 ID 有几行。我正在尝试创建类似变量 positive 的东西。例如,如果在日期范围之间,目标日期在该范围内,则应为该日期范围分配 1,否则为 0。这是一个代码来重现我需要的内容。

ID<-c("4674","4674","4674","4674","4674","4674","4674",   "25694","25694","25694","25694","25694","25694","25694", "92252","92252","92252","92252","92252") 

st_date<-c(NA,NA,"2022-05-09",NA,NA,"2013-07-01","2013-11-27", NA,NA,NA,NA,NA,"2011-04-14","2011-08-04", NA,NA,"2015-08-07","2017-08-18",NA) 

en_date<-c(NA,NA,"2022-06-10",NA,NA,"2013-08-01","2013-12-27", NA,NA,NA,NA,NA,"2011-06-13","2011-08-15", NA,NA,"2015-09-09","2017-09-18",NA) 

targ_date<-c("2022-05-15","2013-05-01",NA,NA,NA,"2013-06-30",NA, NA,NA,NA,NA,NA,"2011-06-13","2011-07-15", NA,NA,"2015-08-20","2017-08-23",NA) 

positive<-c(0,0,1,0,0,0,0, 0,0,0,0,0,1,0, 0,0,1,0,0) 

data<-data.frame(ID,st_date,en_date,targ_date,positive)

我试过:

ds <- ds %>% 
group_by(ID) %>% 
mutate( between_any = as.numeric(inrange(targ_date, st_date, en_date)) ) %>% 
ungroup() 

但它没有做我想做的事。

r 日期 变量 group-by

评论

1赞 alexrai93 8/25/2023
如果同一 ID 有多个日期范围,或者没有日期范围,但有目标,您希望如何处理这种情况?
0赞 Claudio Bravo 8/25/2023
如果每个 ID 有多个日期范围,如果其中一个包含目标日期,则该范围应标记为 1,否则为 0。如果同一 ID 中的多个日期范围包含多个目标日期,则每个日期范围都应标记为 1,否则为 0。如果存在没有日期范围的 ID,则只有 0。这个想法是将每个日期范围标记为 1,这些日期范围包含共享相同 ID 的每组行中的目标日期。我希望这更清楚,并感谢您的帮助。
0赞 alexrai93 8/25/2023
感谢您的澄清 - 请参阅回复,如果不正确,请让我知道我错过了什么。

答:

0赞 alexrai93 8/25/2023 #1

修改了答案,以使用帮助程序函数,该函数在每个 ID 的开始日期和结束日期序列中查找目标日期。

library(dplyr)
library(lubridate)
data<-data.frame(ID,st_date,en_date,targ_date,positive)
data <- data %>% mutate(across(c(targ_date, en_date, st_date), ymd))
data <- split(data, data$ID)

FindMatch <- function(x) {
  targets <- unique(na.omit(x$targ_date))
  
  for(i in 1:length(x$ID)) {
    if(!is.na(x[i,]$st_date)) {
      x$Match[i] <- max(seq.Date(x[i,]$st_date, x[i,]$en_date,by= 1) %in% targets)
    }
    else {
      x$Match[i] <- 0
    }
  }
  return(x)
}

data <- lapply(data, FindMatch)
data <- do.call(rbind, data)

评论

0赞 Claudio Bravo 8/26/2023
抱歉,我刚刚意识到您的解决方案指示了st_dateen_date间隔之间的targ_date。但是,我想指出的是包含至少一个targ_date的时间间隔。请参阅我在此线程开头添加的数据集示例(名为 positive 的变量)。感谢您的帮助。
0赞 alexrai93 8/27/2023
我想我明白了,如果任何范围包含任何目标日期,上面将返回匹配项,除了一个元素外,它与正数对齐,但最终 id 似乎确实有两个匹配项,因为 8 月 23 日在该范围内。