如何按特定间隔对日期时间列进行子集/汇总?

时间:2019-06-11 14:50:43

标签: r datetime time-series

以下是我的数据框的子集。真实的东西大约有3-4个月的数据。基本上,我想做的是通过单个ID值将整个事情子集化(我可以这样做),然后计算在特定时间间隔(例如每6、8或10个小时)记录一次单个ID的次数。因此,例如,如果我的研究在2019年1月1日跨了12个小时,我想从2019年1月1日中午12:00-下午6:00知道ID 5被记录了10次,ID 3被记录了被记录了5次。然后从6:00 PM到12:00 AM,ID 5被记录了4次,ID 3被记录了8次。

structure(list(DateTime = structure(c(1503006715, 1503006880, 
1503007037, 1503007108, 1503007185, 1503007255, 1503007331, 1503007399, 
1503007554, 1503007633, 1503007709, 1503007775, 1503007845, 1503007987, 
1503008057, 1503008132, 1503008199, 1503008269, 1503008392, 1503008412, 
1503008544, 1503008620, 1503009148, 1503009217, 1503009291, 1503009356, 
1503009376, 1503009421, 1503009488, 1503009508, 1503009558, 1503009578, 
1503009634, 1503009702, 1503009722, 1503009774, 1503009854, 1503009875, 
1503009932, 1503010003, 1503010023, 1503010081, 1503010101, 1503010153, 
1503010234, 1503010254, 1503010312, 1503010332, 1503010383, 1503010463, 
1503010483, 1503010538, 1503015897, 1503015963, 1503016024, 1503016873, 
1503017027, 1503017229, 1503022094, 1503022380, 1503022393, 1503022476, 
1503022559, 1503022641, 1503022721, 1503022785, 1503022798, 1503022855, 
1503022868, 1503022931, 1503022944, 1503023000, 1503023013, 1503023073, 
1503023086, 1503023155, 1503023168, 1503023235, 1503023313, 1503023383, 
1503023397, 1503023461, 1503023474, 1503023533, 1503023612, 1503023625, 
1503023686, 1503023816, 1503024252, 1502754012, 1502754224, 1502754364, 
1502754444, 1502754588, 1502754661, 1502754742, 1502754822, 1502758872, 
1502758944, 1502758971, 1502759024, 1502759051, 1502759102, 1502759129, 
1502759200, 1502759278, 1502759351, 1502759407, 1502759434, 1502759515, 
1502768826, 1502768956, 1502769023, 1502769094, 1502769169, 1502769171, 
1502769241, 1502769243, 1502769321, 1502769323, 1502769343, 1502769396, 
1502769399, 1502769464, 1502769536, 1502772897, 1502777244, 1502755140, 
1502755459, 1502755505, 1502755523, 1502755587, 1502755652, 1502755980, 
1502755998, 1502756051, 1502756068, 1502756127, 1502756145, 1502756213, 
1502756268, 1502756286, 1502756350, 1502756367, 1502756428, 1502756446, 
1502756502, 1502756813, 1502756831, 1502756890, 1502756961, 1502756979, 
1502757037, 1502757106, 1502757124, 1502757180, 1502757264, 1502771127, 
1502771205, 1502771276, 1502771278, 1502771356, 1502771358, 1502771432, 
1502771434, 1502771501, 1502771503, 1502771576, 1502771942, 1502775454, 
1502775537, 1502775539, 1502775696, 1502775768, 1502775924, 1502775991, 
1502776063, 1502780243, 1502780322, 1502780532, 1502780686, 1502780764, 
1502780835, 1503275290, 1503275515, 1503275592, 1503275663, 1503275815, 
1503289199, 1503289423, 1503289496, 1503289578, 1503289736, 1503290215, 
1503290345, 1503291075, 1503291154, 1503291296, 1503291366, 1503295707
), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    Receiver = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 5L, 2L, 5L, 5L, 5L, 5L, 
    5L, 5L, 2L, 5L, 5L, 2L, 5L, 2L, 5L, 5L, 2L, 5L, 5L, 2L, 5L, 
    5L, 2L, 5L, 2L, 5L, 5L, 2L, 5L, 2L, 5L, 5L, 2L, 5L, 13L, 
    13L, 10L, 10L, 10L, 10L, 31L, 6L, 31L, 31L, 31L, 31L, 31L, 
    6L, 31L, 6L, 31L, 6L, 31L, 6L, 31L, 6L, 31L, 6L, 31L, 6L, 
    6L, 6L, 31L, 6L, 31L, 6L, 6L, 31L, 6L, 6L, 6L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 15L, 15L, 8L, 15L, 8L, 15L, 8L, 8L, 8L, 
    8L, 15L, 8L, 8L, 35L, 35L, 35L, 35L, 3L, 35L, 3L, 35L, 3L, 
    35L, 31L, 3L, 35L, 3L, 3L, 32L, 32L, 2L, 2L, 5L, 2L, 2L, 
    2L, 5L, 2L, 5L, 2L, 5L, 2L, 2L, 5L, 2L, 5L, 2L, 5L, 2L, 5L, 
    5L, 2L, 5L, 5L, 2L, 5L, 5L, 2L, 5L, 5L, 35L, 35L, 3L, 35L, 
    3L, 35L, 3L, 35L, 3L, 35L, 35L, 3L, 3L, 3L, 35L, 3L, 3L, 
    3L, 3L, 35L, 32L, 32L, 32L, 32L, 32L, 32L, 5L, 2L, 2L, 2L, 
    2L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L), .Label = c("VR2AR-546711", 
    "VR2AR-546712", "VR2AR-546714", "VR2AR-546715", "VR2AR-546718", 
    "VR2AR-546720", "VR2AR-546721", "VR2AR-546730", "VR2AR-546731", 
    "VR2AR-546732", "VR2AR-546733", "VR2AR-546734", "VR2AR-546735", 
    "VR2AR-546736", "VR2AR-546745", "VR2W-131176", "VR2W-131303", 
    "VR2W-131304", "VR2W-131305", "VR2W-131306", "VR2W-131307", 
    "VR2W-131308", "VR2W-131309", "VR2W-131310", "VR2W-131311", 
    "VR2W-131312", "VR2W-131313", "VR2W-131314", "VR2W-131315", 
    "VR2W-131316", "VR2W-131317", "VR2W-131318", "VR2W-131319", 
    "VR2W-131320", "VR2W-131997"), class = "factor"), ID = c(1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 
    1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1657L, 1658L, 1658L, 
    1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 
    1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 
    1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 
    1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 1658L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 1659L, 
    1659L, 1659L, 1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 
    1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 1660L, 
    1660L)), row.names = c(NA, 200L), class = "data.frame")

编辑:

我还想在每个时间范围内增加一列唯一接收器的数量,因此理想情况下输出看起来像这样。

> df
# A tibble: 20 x 4
# Groups:   ID [5]
      ID DateHour                n nReceivers
   <int> <dttm>              <int>      <int>
 1  1657 2017-08-17 12:00:00     5         2
 2  1657 2017-08-17 18:00:00    47         12
 3  1657 2017-08-18 18:00:00    37         12
 4  1658 2017-08-14 18:00:00     8         11
 5  1658 2017-08-15 00:00:00     2          2
 6  1658 2017-08-15 18:00:00    28         11
 7  1659 2017-08-14 18:00:00     1         1
 8  1659 2017-08-15 00:00:00    26          9
 9  1659 2017-08-15 18:00:00    29          6
10  1660 2017-08-21 00:00:00    41         13
11  1660 2017-08-21 06:00:00    45         15
12  1660 2017-08-21 12:00:00    20         10
13  1660 2017-08-21 18:00:00     5         3
14  1661 2017-08-28 12:00:00     3         1
15  1661 2017-08-28 18:00:00    56         11
16  1661 2017-08-29 06:00:00     1         1
17  1661 2017-08-29 12:00:00   106         13
18  1661 2017-08-29 18:00:00    48         12
19  1661 2017-08-30 06:00:00    35          9
20  1661 2017-08-31 00:00:00    35         12

1 个答案:

答案 0 :(得分:1)

我相信以下功能可以满足您的需求。
它将按ID和日期/小时分组,并计算每个分组的行数。返回值是一个包含3列的数据帧,ID,一个DateHour列,其中包含该时段的初始小时,而n,则是计数。

library(lubridate)
library(dplyr)

countFun <- function(DF, span = 6){
  DF %>%
    group_by(ID) %>%
    mutate(DateHour = ymd_h(format(DateTime, "%Y-%m-%d %H")),
           DateHour = (hour(DateTime) %/% span)*span,
           DateHour = ymd_h(paste(as.Date(DateTime), DateHour))) %>%
    ungroup() %>%
    group_by(ID, DateHour) %>%
    summarise(n = n(),
              nReceivers = n_distinct(Receiver))
}

countFun(df1)
## A tibble: 11 x 4
## Groups:   ID [4]
#      ID DateHour                n nReceivers
#   <int> <dttm>              <int>      <int>
# 1  1657 2017-08-17 12:00:00     5          1
# 2  1657 2017-08-17 18:00:00    47          2
# 3  1657 2017-08-18 18:00:00    37          4
# 4  1658 2017-08-14 18:00:00     8          1
# 5  1658 2017-08-15 00:00:00     2          1
# 6  1658 2017-08-15 18:00:00    28          5
# 7  1659 2017-08-14 18:00:00     1          1
# 8  1659 2017-08-15 00:00:00    26          3
# 9  1659 2017-08-15 18:00:00    29          2
#10  1660 2017-08-21 00:00:00    12          1
#11  1660 2017-08-21 18:00:00     5          2

countFun(df1, 3)  # output omitted