分组并总结条件日期范围方面 - dplyr?

New*_*100 4 r data-manipulation lubridate dplyr

披露 - 这是我的第一个 SO 问题,如果这是一个重复的问题,我深表歉意,但我已经找了一段时间,但没有找到这个特定场景的答案

R 版本:3.4.2

我想要一种按特定标识符对数据进行分组的有效方法,然后根据条件进行汇总 - 对每一行动态进行。具体来说,如果另一个实例在当前行的 1 年内,则按 ID 分组,然后总结另一个变量发生的实例(紧急访问)的数量。

以下是数据开始时的示例:

更新以包含 2 个紧急案例的示例

library(lubridate)
   > dat <- data.frame("ID" = c(6,6,6,7,7,10,11,11,11),
                      "Admit_Dt" = as.Date(c('2013-08-12', '2013-12-12', '2016-01-03','2011-04-01', '2011-09-20','2012-02-19','2014-06-24','2014-08-12','2014-09-01')), 
                      "Urgent" = c(0,1,1,1,0,0,1,1,1)) 
   > dat

| ID | Admit_Dt   | Urgent|
|  6 | 2013-08-12 |      1| 
|  6 | 2013-12-12 |      0|
|  6 | 2016-01-03 |      1|
|  7 | 2011-04-01 |      1|
|  7 | 2011-09-20 |      0|
| 10 | 2012-02-19 |      0|
| 11 | 2014-06-24 |      1|
| 11 | 2014-08-12 |      1|
| 11 | 2014-09-01 |      1|
Run Code Online (Sandbox Code Playgroud)

我想首先按 ID 分组,然后总结给定组的每个 Admit_Dt 一年内发生的紧急访问次数。

下面这个过于复杂的代码产生了我想要的,但我正在使用的数据集非常大,而且效率很低。我很好奇是否有一种使用“dplyr”来实现我想要做的事情的方法:

   > dat$Urgent_1yrSum <- unlist(sapply(1:length(unique(dat$ID)), function(i) {
    grouped <-  subset(dat, ID == unique(dat$ID)[i])
      output <- do.call(rbind, lapply(1:nrow(grouped), function(y){
    urgent_sum_1year <- sum(grouped[grouped$Admit_Dt < grouped$Admit_Dt[y] & grouped$Admit_Dt > (grouped$Admit_Dt[y] - dyears(1)), "Urgent"])
     }))
      return(output)
}
))

> dat
| ID | Admit_Dt   | Urgent| Urgent_1yrSum|
|  6 | 2013-08-12 |      1|          0|
|  6 | 2013-12-12 |      0|          1|
|  6 | 2016-01-03 |      1|          0|
|  7 | 2011-04-01 |      1|          0|
|  7 | 2011-09-20 |      0|          1|
| 10 | 2012-02-19 |      0|          0|
| 11 | 2014-06-24 |      1|          0|
| 11 | 2014-08-12 |      1|          1|
| 11 | 2014-09-01 |      1|          2|
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!!

Mik*_*ike 5

我无法让你的代码工作,所以我试着看看我是否能让它工作。我首先加入内部以通过 ID 获取所有日期组合。当您减去它们时,您可以使用过滤器查看每个日期的一年内谁收到了访问,然后summarise

dat <- data.frame("ID" = c(6,6,6,7,7,10,11,11),
                  "Admit_Dt" = c('2013-08-12', '2013-12-12', '2016-01-03','2011-04-01', '2011-09-20','2012-02-19','2014-06-24','2014-08-12'), 
                  "Urgent" = c(0,1,1,1,0,0,1,1),stringsAsFactors = FALSE)
library(dplyr)


dat2 <- inner_join(dat,select(dat,ID,Admit_Dt,Urgent),by = "ID") %>% 
        #Inner Join by ID to get every combo of dates
        #Subtract dates from eachother 
        mutate(datediff = as.Date(Admit_Dt.x) - as.Date(Admit_Dt.y),
               ID = ID) %>%
        #get dates that occured within one year of visit
        #for each date
        filter(datediff > 0 & datediff <= 365) %>% 
        #group by person
        group_by(ID,Admit_Dt.x) %>% 
        #count urgent visits
       mutate(urgent_visits = max(Urgent.x,Urgent.y,na.rm=TRUE)) %>% 
    summarise(vs = sum(urgent_visits))
#Join back on to df

dat3 <- left_join(dat,dat2,by = c("ID" = "ID", "Admit_Dt"="Admit_Dt.x"))
Run Code Online (Sandbox Code Playgroud)