【问题标题】:R - Rolling sum based on dates, with a condition per groupR - 基于日期的滚动总和,每组有一个条件
【发布时间】:2021-12-28 14:45:09
【问题描述】:

我有以下数据集。

根据每一行的“start_date_event”,我已经总结了各个事件在 60 天范围内(变量sum_days)发生的所有天数开始日期。

但是,有一个条件,例如,必须考虑总和大于 15 天。 因此,对于超过 15 天的事件,我想将“0”分配给属于相应期间的所有行。

预期输出:

预期结果示例:第 2 行已变为 0,因为它包含在总和大于 15 天的前一行的范围内。第 2 行记录的事件开始于 2019 年 2 月 28 日,属于 2019 年 1 月 1 日(事件开始)至 2019 年 3 月 6 日(60 天间隔结束,2019 年 1 月 1 日)期间+ 60) 总和大于 15 的第一行。

有人有什么建议吗?

可重现的例子:

library(data.table)
library(dplyr)

# Input data
data <- data.table(id = c("Group A", "Group A", "Group A", "Group A",
                          "Group B", "Group B"),
                   start_date_event = c("2019-01-01",
                                        "2019-02-28",
                                        "2019-03-13",
                                        "2019-03-19",
                                        "2020-04-02",
                                        "2020-05-15"),
                   end_date_event = c("2019-01-05",
                                      "2019-03-12",
                                      "2019-03-18",
                                      "2019-03-20",
                                      "2020-05-06",
                                      "2020-05-16"))

# Convert to date
data <- data %>%
          dplyr::mutate(start_date_event = as.Date(start_date_event)) %>%
          dplyr::mutate(end_date_event = as.Date(end_date_event)) %>%
          dplyr::mutate(days_diff = as.integer(end_date_event - start_date_event)) %>%
          dplyr::mutate(end_interval = end_date_event + 60) %>%
          data.table::setDT()

# Calculating cumulative sum within 60 days
data[.(c = id, tmin = start_date_event,
       tmax = start_date_event + 60),
   on = .(id == c, start_date_event <= tmax,
          start_date_event >= tmin),
   sum_days := sum(days_diff), by = .EACHI]

【问题讨论】:

  • 不确定我是否理解输出,为什么最后一行变成了 0?
  • 各个时期是如何定义的? start_date_eventend_interval?
  • @cgvoller 最后一行应该为 0,因为它在前一行的 60 天间隔(2020-04-02 到 2020-07-05)内开始(2020-05-15)总和> 15
  • @Matt start_date_event 表示某个事件(例如服务)的开始日期。 end_interval 是从 start_date_event 算起的 60 天之和的结果。正在考虑 60 天的“窗口”进行计算。

标签: r date datatable cumulative-sum


【解决方案1】:

这应该可行:

library(sqldf)
library(dplyr)
library(data.table)

# Creating a new 'row column'
data$row_n <- 1:nrow(data)

# Identifying which lines overlap and then filtering data
data <- sqldf("select a.*, 
                      coalesce(group_concat(b.rowid), '') as overlaps
               from data a
               left join data b on a.id = b.id and 
                                   not a.rowid = b.rowid and
                                   ((a.start_date_event between
                                     b.start_date_event and b.end_interval) or
                                    (b.start_date_event between a.start_date_event
                                     and a.end_interval))
               group by a.rowid
               order by a.rowid") %>%
               group_by(id) %>%
               mutate(row_n = as.character(row_n),
                      previous_row = dplyr::lag(row_n, n = 1, default = NA),
                      previous_value = dplyr::lag(sum_days, n = 1, default = NA),
                      sum2 = case_when(mapply(grepl,previous_row, overlaps) == TRUE &
                                         previous_value > 15 ~ as.integer(0),
                                       TRUE ~ sum_days),
                      previous_value = dplyr::lag(sum2, n = 1, default = NA),
                      sum2 = case_when(mapply(grepl,previous_row, overlaps) == TRUE &
                                         previous_value > 15 ~ as.integer(0),
                                       TRUE ~ sum_days)) %>%
               dplyr::select(-c(previous_value, previous_row, row_n))

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 2021-01-16
    • 2018-09-20
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    相关资源
    最近更新 更多