【问题标题】:Conditional cumulative sum in R with dplyr. All dates before current date使用 dplyr 在 R 中的条件累积和。当前日期之前的所有日期
【发布时间】:2021-11-06 13:27:33
【问题描述】:

我正在寻找一种在 R 中使用累积和的方法,条件是不包括当前日期。

我有以下数据框(它是真实数据框的子集和简化版本):

df <- structure(list(date_time = structure(c(1609513200, 1609513200, 1609513200,
  1609516800, 1609516800, 1609516800, 1609599600, 1609599600, 1609599600, 
  1609603200, 1609603200, 1609603200), tzone = "UTC", class = c("POSIXct", 
  "POSIXt")), event = c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L), 
  person = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A", "B", "C"), 
  did_attend = c(1L, 1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 1L), 
  events_attended = c(0, 0, 0, 1, 1, 1, 2, 2, 1, 2, 3, 2), 
  events_attended_desired = c(0L, 0L, 0L, 0L, 0L, 0L, 2L, 2L, 1L, 2L, 2L, 1L)), 
  class = c("grouped_df", "tbl_df", "tbl", "data.frame"), 
  row.names = c(NA, -12L), groups = structure(list(person = c("A", "B", "C"),
  .rows = structure(list(c(1L, 4L, 7L, 10L), c(2L, 5L, 8L, 11L), 
  c(3L, 6L, 9L, 12L)), ptype = integer(0), 
  class = c("vctrs_list_of", "vctrs_vctr", "list"))), 
  class = c("tbl_df", "tbl", "data.frame"), 
  row.names = c(NA, -3L), .drop = TRUE))
 
 df
 ## date_time           event person did_attend events_attended events_attended_desired
 ## 2021-01-01 15:00:00     1 A               1               0                       0
 ## 2021-01-01 15:00:00     1 B               1               0                       0
 ## 2021-01-01 15:00:00     1 C               1               0                       0
 ## 2021-01-01 16:00:00     2 A               1               1                       0
 ## 2021-01-01 16:00:00     2 B               1               1                       0
 ## 2021-01-01 16:00:00     2 C               0               1                       0
 ## 2021-01-02 15:00:00     1 A               0               2                       2
 ## 2021-01-02 15:00:00     1 B               1               2                       2
 ## 2021-01-02 15:00:00     1 C               1               1                       1
 ## 2021-01-02 16:00:00     2 A               1               2                       2
 ## 2021-01-02 16:00:00     2 B               0               3                       2
 ## 2021-01-02 16:00:00     2 C               1               2                       1

“did_attend”列是一个虚拟变量,表示一个人是否参加了活动。 “events_attended”专栏显然是由

events <- events %>% 
  arrange(date_time) %>% 
  group_by(person) %>% 
  mutate(events_attended = lag(cumsum(did_attend), default = 0)) %>% 
  ungroup()

现在我正在寻找一种不包括当前日期的事件的方法,因此累积总和应该只对当前日期之前的日期求和(所需的输出在 events_attended_desired 列中)。每天有几个活动,每天的活动数量不同。所以滞后版本不起作用。我在 cumsum 函数中尝试了几个 ifelse() 但它们也不起作用,因为我不知道如何比较 cumsum() 中 ifelse 子句中的日期

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这是一种使用dplyrlubridate::floor_date 的方法。

    首先,我在数据框中添加一个“日期”列,以便我可以根据日期进行汇总和连接。

    然后我将这个表加入到它自身的一个总结版本中。 count(date, wt = did_attend)group_by(date) %&gt;% summarize(n = sum(did_attend)) 的快捷方式,所以如果我再利用它的滞后,我们会得到想要的结果。

    df2 <- df %>%
      mutate(date = lubridate::floor_date(date_time, "day"))
    
    df2 %>%
      left_join(
        df2 %>% 
          count(date, wt = did_attend) %>%
          mutate(prior_attended = cumsum(lag(n, default = 0))) %>%
          select(-n)
      )
    

    【讨论】:

      【解决方案2】:

      如果每个数字对应于先前的日期,则将其乘以 1,否则将其乘以 0。

       library(dplyr)
       df %>% 
         mutate(events_attended = sapply(as.Date(date_time), 
            function(x) sum((as.Date(date_time) < x) * did_attend))) %>%
         arrange(date_time) %>%
         ungroup
      

      【讨论】:

      • 这很好用。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多