【问题标题】:2 week sum ending on every second Tuesday每周第二个星期二结束的 2 周总和
【发布时间】:2020-07-11 07:38:13
【问题描述】:

我有一些格式类似于以下可重现示例的数据(问题下方的数据输入代码,最后)。两件事:

  1. 并非所有日期都有值(即缺少许多日期)。
  2. 某些日期有多个值,例如 2020 年 6 月 16 日。
#>        date value
#> 1 30-Jun-20    20
#> 2 29-Jun-20  -100
#> 3 26-Jun-20    -4
#> 4 16-Jun-20   -13
#> 5 16-Jun-20    40
#> 6  9-Jun-20    -6

对于在星期二结束的两个星期期间,我想取 value 列的总和。

所以在上面的示例数据中,我想总结:

  • 在 2020 年 6 月 16 日星期二结束的两周(即从 2020 年 6 月 3 日至 2020 年 6 月 16 日,含)
  • 2020 年 6 月 30 日星期二结束的两周(2020 年 6 月 17 日 - 2020 年 6 月 30 日包括在内)
  • 我最终希望代码能够继续对在每个第二个星期二结束的所有两周时间段进行求和,以便有更多数据时。

所以我想要的输出是:

#2_weeks_end     total
#30-Jun-20    -84
#16-Jun-20     21

Tidyverse 和 lubridate 解决方案是我的首选。

数据输入代码如下:

df <- data.frame(
  stringsAsFactors = FALSE,
                date = c("30-Jun-20","29-Jun-20",
                       "26-Jun-20","16-Jun-20","16-Jun-20","9-Jun-20"),
                value = c(20L, -100L, -4L, -13L, 40L, -6L)
)
df

【问题讨论】:

    标签: r dplyr tidyverse lubridate


    【解决方案1】:

    使用 findInterval() 的解决方案。

    df$date <- dmy(df$date)
    df_intervals <- seq(as.Date("2020-06-03"), as.Date("2020-06-03")+14*3, 14)
    
    df %>%
      mutate(interval = findInterval(date, df_intervals)) %>%
      mutate(`2_weeks_end` = df_intervals[interval+1]-1) %>%
      group_by(`2_weeks_end`) %>%
      summarise(total= sum(value))
    

    返回:

    # A tibble: 2 x 2
      2_weeks_end   total
      <date>     <int>
    1 2020-06-16    21
    2 2020-06-30   -84
    

    【讨论】:

      【解决方案2】:

      如果您喜欢每周或默认为lubridate 的任何其他单位,这里有一个选项:

      library(dplyr)
      library(lubridate)
      df%>%
          mutate(date = as.Date(date, format = "%d-%b-%y"))%>%
          group_by(week_ceil = ceiling_date(date - 1L, unit = "week", week_start = 2L))%>%
          summarize(sums = sum(value))
      

      这是一个 方法,它创建一个引用表,后跟一个非等连接:

      library(data.table)
      setDT(df)
      df[, date := as.Date(date, format = "%d-%b-%y")]
      
      ref_dt = df[,  .(beg_date = seq.Date(from = floor_date(min(date), unit = "week", week_start = 3L),
                     to = max(date), 
                     by =  "2 weeks"))]
      ref_dt[, end_date := beg_date +13L]
      
      df[ref_dt, 
         on = .(date > beg_date,
                date <= end_date),
         sum(value),
         by = .EACHI]
      
      ##         date       date  V1
      ##1: 2020-06-03 2020-06-16  21
      ##2: 2020-06-17 2020-06-30 -84
      

      【讨论】:

      • 用你的lubridate 回答,在代码给我每周总计之后,有没有简单的方法来获得我正在寻找的 2 周总计?您是否建议只使用滞后运算符求和,然后每隔一行过滤一次?还是有更简单的方法?
      • 我不相信有一种简单的方法可以让它达到 2 周的总数 - 但我认为即使它不能真正回答你的要求,它仍然足够好。您的想法很好,但您还需要考虑缺少的几周。也就是说,如果 2020 年 1 月 1 日没有发生任何事情,则将没有要过滤的记录。所以...如果您可以简化并假设每个双周周期都有结果,那么可能还有其他方法。
      猜你喜欢
      • 2020-07-26
      • 1970-01-01
      • 2018-05-26
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      相关资源
      最近更新 更多