【问题标题】:Is there a way to sum data grouping by date with a time period?有没有办法按日期和时间段来汇总数据分组?
【发布时间】:2020-04-23 11:52:03
【问题描述】:

我有将时间段(实际上是开始日期和结束日期)和连续值相关联的数据。 我想找到一种方法来计算该时间段内每一天的第三个变量的值。

以这张表为例:

       START        END NUMBER
1  2020-03-16 2020-05-31      5
2  2020-03-16 2020-06-30      7
3  2020-03-17 2020-08-31      1

有一个新表:

DAY        SUM
2020-03-16    12
2020-03-17    13
2020-03-18    13
...
2020-05-31    13
2020-06-01    8
...

等等。有没有办法做到这一点?也许在 lubridate 的帮助下? 谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    试试:

    library(data.table)
    
    setDT(df)[, c('START', 'END') := lapply(.SD, function(x) as.Date(as.character(x))), .SDcols = 1:2][
      , .(DAY = seq(START, END, by = 'day'), NUMBER = NUMBER), by = 1:nrow(df)][
        , .(SUM = sum(NUMBER)), by = DAY]
    

    输出:

                DAY SUM
      1: 2020-03-16  12
      2: 2020-03-17  13
      3: 2020-03-18  13
      4: 2020-03-19  13
      5: 2020-03-20  13
     ---               
    165: 2020-08-27   1
    166: 2020-08-28   1
    167: 2020-08-29   1
    168: 2020-08-30   1
    169: 2020-08-31   1
    

    【讨论】:

      【解决方案2】:

      另一个使用非等连接的data.table 选项:

      ans <- DT[.(DATE=seq(min(START), max(END), by="1 day")), on=.(START<=DATE, END>=DATE), 
          by=.EACHI, .(SUM=sum(NUMBER))][, (1L) := NULL][]
      setnames(ans, "END", "DAY")[]
      

      输出:

                  DAY SUM
        1: 2020-03-16  12
        2: 2020-03-17  13
        3: 2020-03-18  13
        4: 2020-03-19  13
        5: 2020-03-20  13
       ---               
      165: 2020-08-27   1
      166: 2020-08-28   1
      167: 2020-08-29   1
      168: 2020-08-30   1
      169: 2020-08-31   1
      

      数据:

      library(data.table)
      DT <- fread("START        END NUMBER
      2020-03-16 2020-05-31      5
      2020-03-16 2020-06-30      7
      2020-03-17 2020-08-31      1")
      cols <- c("START", "END")
      DT[, (cols) := lapply(.SD, as.IDate, format="%Y-%m-%d"), .SDcols=cols]
      

      【讨论】:

        【解决方案3】:

        1) Base R 使用末尾注释中可重复显示的数据 lapply over erach 行,使用 seq 将日期范围扩展为日期序列。这给出了一个列表,每个输入行一个组件,我们将它们绑定在一起,给出long。然后通过Date 聚合long。没有使用任何包。

        expand <- function(i, data) with(data[i, ], 
          data.frame(Date = seq(START, END, "day"), NUMBER)
        )
        
        long <- do.call("rbind", lapply(1:nrow(DF), expand, data = DF))
        result <- aggregate(NUMBER ~ Date, long, sum)
        
        head(result)
        

        给予:

                Date NUMBER
        1 2020-03-16     12
        2 2020-03-17     13
        3 2020-03-18     13
        4 2020-03-19     13
        5 2020-03-20     13
        6 2020-03-21     13
        

        2) dplyr 展开rowwise 代码中的每一行,然后在group_by 代码中将NUMBERDate 相加。

        library(dplyr)
        
        DF %>%
          rowwise %>%
          do(data.frame(Date = seq(.$START, .$END, "day"), NUMBER = .$NUMBER)) %>%
          ungroup %>%
          group_by(Date) %>%
          summarize(NUMBER = sum(NUMBER)) %>%
          ungroup
        

        注意

        Lines <- "       START        END NUMBER
        1  2020-03-16 2020-05-31      5
        2  2020-03-16 2020-06-30      7
        3  2020-03-17 2020-08-31      1"
        DF <- read.table(text = Lines)
        DF[1:2] <- lapply(DF[1:2], as.Date)
        

        【讨论】:

          猜你喜欢
          • 2012-02-29
          • 1970-01-01
          • 2021-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 2021-02-04
          • 1970-01-01
          相关资源
          最近更新 更多