在 R 中总结日期和时间边界内的观察结果

Summarizing observations within date and time boundaries in R

我有一个名为 ActiveData 的数据框,它显示了单个 ID 活动时的日期和时间(StartDTEndDT)。 Active is structured like this where StartDTandEndDT` 的格式为 mdy_hms:

ID         StartDT               EndDT
1  05/05/2021 8:15:00    05/05/2021 9:15:00
2  05/05/2021 8:15:00    05/05/2021 9:15:00
3  05/05/2021 8:15:00    05/05/2021 10:15:00
…

我有另一个名为 Observations 的数据框,它显示每个 ID 观察到自己或另一个 ID 满足某个变量的观察结果。这里,ID表示观察者,IDobserved表示观察到哪个ID满足变量(ID也可以观察自己)。

ID       DT                          IDobserved
1      05/05/2021 8:19:00                1
1      05/05/2021 8:20:00                1      
1      05/05/2021 8:19:00                2
2      05/05/2021 8:19:20                1
2      05/05/2021 8:19:45                3
3      05/05/2021 8:19:00                1
3      05/05/2021 8:20:00                1
3      05/05/2021 8:25:00                1
3      05/05/2021 8:45:00                3
3      05/05/2021 8:19:00                2
…

我想总结每个ID观察到其他IDs(包括他们自己)在StartDT和[=指定的时间限制内满足变量的次数ActiveData 数据帧中的 15=],因此最终的 table 将指定观察次数,以及每个 ID 主动观察的边界之间经过的时间(以秒为单位) (在 ActiveData 中的 StartDTEndDT 之间)。所以对于上面的数据,最终的 table 看起来像这样:

ID   IDobserved   Observations      TimeElapsed
1         1            2             3600
1         2            1             3600
2         1            1             3600
2         3            1             3600
3         1            3             7200
3         2            1             7200
3         3            1             7200

如何做到这一点?

这是一个使用data.table的方法。

  1. 使用setDT
  2. data.frame转换为data.table
  3. 将两个数据集中的 'DT'、'StartDT'、'EndDT' 列转换为日期时间 class (mdy_hms)
  4. 在第二个数据集 (df2) 中创建 'Observations' 列作为每个组 ID 的观察数,IDobserved
  5. 与 ID 列上的第一个数据进行连接,指定,通过使用 difftime 和 return [=19] 获取 DT、StartDT、EndDT 列之间的差异总和来进行汇总=]行
library(data.table)
library(lubridate)
setDT(df1)[, c('StartDT', 'EndDT') := lapply(.SD, mdy_hms),
       .SDcols = 2:3]
setDT(df2)[, DT := mdy_hms(DT)]
df2[, Observations := .N, .(ID, IDobserved)]
unique(df2[df1, .(IDobserved, Observations,
      TimeElapsed = as.numeric(difftime(DT, StartDT, units = 'sec') +
        difftime(EndDT, DT, units = 'sec'))), on = .(ID), by = .EACHI])

-输出

    ID IDobserved Observations TimeElapsed
1:  1          1            2        3600
2:  1          2            1        3600
3:  2          1            1        3600
4:  2          3            1        3600
5:  3          1            3        7200
6:  3          3            1        7200
7:  3          2            1        7200

数据


df1 <- structure(list(ID = 1:3, StartDT = c("05/05/2021 8:15:00", 
"05/05/2021 8:15:00", 
"05/05/2021 8:15:00"), EndDT = c("05/05/2021 9:15:00", "05/05/2021 9:15:00", 
"05/05/2021 10:15:00")), class = "data.frame", row.names = c(NA, 
-3L))

df2 <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), 
    DT = c("05/05/2021 8:19:00", "05/05/2021 8:20:00", "05/05/2021 8:19:00", 
    "05/05/2021 8:19:20", "05/05/2021 8:19:45", "05/05/2021 8:19:00", 
    "05/05/2021 8:20:00", "05/05/2021 8:25:00", "05/05/2021 8:45:00", 
    "05/05/2021 8:19:00"), IDobserved = c(1L, 1L, 2L, 1L, 3L, 
    1L, 1L, 1L, 3L, 2L)), class = "data.frame", row.names = c(NA, 
-10L))

很酷的问题!用你的数据

ActiveData <- tibble::tribble(
  ~ID, ~StartDT,             ~EndDT,
  1,   "05/05/2021 8:15:00", "05/05/2021 9:15:00",
  2,   "05/05/2021 8:15:00", "05/05/2021 9:15:00",
  3,   "05/05/2021 8:15:00", "05/05/2021 10:15:00"
)

Observations <- tibble::tribble(
  ~ID, ~DT,                ~IDobserved,
  1,   "05/05/2021 8:19:00", 1,
  1,   "05/05/2021 8:20:00", 1,
  1,   "05/05/2021 8:19:00", 2,
  2,   "05/05/2021 8:19:20", 1,
  2,   "05/05/2021 8:19:45", 3,
  3,   "05/05/2021 8:19:00", 1,
  3,   "05/05/2021 8:20:00", 1,
  3,   "05/05/2021 8:25:00", 1,
  3,   "05/05/2021 8:45:00", 3,
  3,   "05/05/2021 8:19:00", 2
)

我愿意

library(dplyr)

fmt <- "%d/%m/%Y %H:%M:%S"

ActiveData %>%
  mutate(across(-ID, ~ as.POSIXct(., format = fmt))) %>%
  purrr::pmap(\(...) {
    args <- list(...)
    Observations %>%
      mutate(DT = as.POSIXct(DT, format = fmt)) %>%
      filter(DT >= args$StartDT, DT <= args$EndDT, ID == args$ID) %>%
      count(ID, IDobserved, name = "Observations") %>%
      mutate(TimeElapsed = difftime(args$EndDT,
                                    args$StartDT,
                                    units =  "secs"))
  }) %>%
  bind_rows()

回归

# A tibble: 7 x 4
     ID IDobserved Observations TimeElapsed
  <dbl>      <dbl>        <int> <drtn>
1     1          1            2 3600 secs
2     1          2            1 3600 secs
3     2          1            1 3600 secs
4     2          3            1 3600 secs
5     3          1            3 7200 secs
6     3          2            1 7200 secs
7     3          3            1 7200 secs