分组依据并使用条件日期范围方面进行汇总-dplyr?

分组依据并使用条件日期范围方面进行汇总-dplyr?,r,dplyr,data-manipulation,lubridate,R,Dplyr,Data Manipulation,Lubridate,披露-这是我的第一个SO问题,如果这是一个重复的问题,我很抱歉,但我已经寻找了一段时间,没有找到这个特定场景的答案 R版本:3.4.2 我想要一种有效的方法,通过某个标识符对数据进行分组,然后根据一个条件对每一行进行动态汇总。具体来说,按ID分组,然后求和另一个变量发生的实例数(紧急访问),如果另一个实例在当前行的1年内 以下是数据开始时的示例: 更新以包括2个紧急案例的示例 library(lubridate) > dat <- data.frame("ID" = c(6,6

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

R版本:3.4.2

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

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

更新以包括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|
库(lubridate)
>dat dat
|ID |承认|紧急|
|  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|
我想先按ID分组,然后计算出某一组在每次入院后一年内发生的紧急就诊次数

下面这段过于复杂的代码产生了我想要的结果,但是我使用的数据集非常大,我认为这是非常低效的。我很好奇是否有一种使用“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|

>dat$emergency\u 1yrSum我无法让你的代码正常工作,所以我试着看看能否让它正常工作。我首先通过内部连接按ID获取所有日期组合。减去它们后,您可以使用过滤器查看在每个日期的一年内谁收到了访问,然后进行总结

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"))
dat%
#获取访问后一年内发生的日期
#每个日期
过滤器(datediff>0和datediff%
#分组
分组依据(ID,接纳量x)%>%
#计算紧急访问次数
突变(紧急访问量=最大值(紧急.x,紧急.y,na.rm=TRUE))%>%
总结(vs=总和(紧急访问))
#重新加入df

dat3这里有一个答案,使用的是
dplyr
、列表列和
purrr
。我假设没有重复的
ID
Admit\u Dt
,否则我很确定这不正确

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 = F)


library(dplyr)
library(purrr)
library(lubridate)

isUrgentAndWithinYear <- function(urgent, date, date1){
     sum( urgent == 1 & abs(as.numeric(difftime(date, date1, units = "weeks"))) < 52)
} 

dat %>%
     mutate(Admit_Dt = ymd(Admit_Dt)) %>% 
     group_by(ID) %>%
     mutate(urgents = list(Urgent),
            admits = list(Admit_Dt)
            )%>% 
     group_by(ID, Admit_Dt) %>% 
     mutate(Urgent_1yrSum = map2_dbl(urgents, admits, ~ isUrgentAndWithinYear(.x, .y, Admit_Dt) )) %>% 
     mutate(Urgent_1yrSum = Urgent_1yrSum - Urgent) %>% 
     select(-urgents, -admits)
dat%
分组依据(ID)%>%
突变(紧急=列表(紧急),
允许=列表(允许)
)%>% 
分组人(身份证、录取通知书)%>%
突变(紧急年数=map2 dbl(紧急年数,允许年数,~Isurgent和年内(.x,.y,允许年数))%>%
突变(紧急\u 1yrSum=紧急\u 1yrSum-紧急)%>%
选择(-urgents,-empts)

我在e1+(-e2)中得到错误
错误:二进制运算符的非数字参数
在尝试代码时,我认为出现错误是因为示例数据中的admission_Dt不是作为日期类构造的。我在创建df时添加了'as.date'。你确定你的最后一行是正确的吗?应该改为2014-09-01的admission_Dt吗?已更新!抱歉,生成虚假数据比要求更难回答实际问题哈哈。这给了
2011-09-20
一个错误的计数。我想你必须保留
紧急
列的另一份副本,然后执行
max(紧急.x,紧急.y)
而不是
sum(紧急)
既然您想检查两个日期中是否有一个是紧急访问。或者可能是一个cumsum..不确定,因为示例只涉及一个。@strawberryBeef您完全正确,我切换到max,它给出了期望的结果非常感谢您@Mike-使用sum更新,效果非常好!我非常感谢您的帮助。