【问题标题】:How to find the number of hours that is part of a start and end date period based on conditions in r如何根据 r 中的条件查找属于开始和结束日期期间的小时数
【发布时间】:2020-08-26 18:51:20
【问题描述】:

我有两个表,第一个表有列 - ID、Start_Date、End_Date 第二个表有列 - Day_of_Week、Start_Time、End_Time

      ID     Start_Date_Time       End_Date_Time
1 ABC123 2019-01-05 16:00:00 2019-01-07 20:00:00
2 XYZ123 2019-01-06 05:00:00 2019-01-13 05:00:00
3 XYZ456 2019-01-08 19:00:00 2019-01-13 12:00:00

还有

      ID      Day StartTime EndTime
1 ABC123 Saturday     13:00   18:00
2 XYZ123   Sunday      0:00    6:00
3 XYZ456  Tuesday      0:00   12:00

我需要第一个表中的 Resultant 列,它根据第二个表中的条件捕获 Start_Date 和 End_Date 内的小时数。在这种情况下,结果应该是

ID        Start_Date          End_Date           Timeline_Hours
ABC123    01/05/2019 16:00    01/07/2019 20:00        2
XYZ123    01/06/2019 5:00     01/13/2019 5:00         6
XYZ456    01/08/2019 19:00    01/13/2019 12:00        0

对于第一条记录:ABC123 - 基于条件的 Start_Date 和 End_date 的小时数为 2 小时。

原因 - 日期从 Staurday 16:00 (4PM) 开始,到星期一 20:00 (8PM) 结束,第二张表中的条件是星期六 13:00 到 18:00,因此重叠时间为 2 小时(从 16:00 开始到 18:00)

类似地,第二个持续时间超过一周,第一周重叠为 1 小时(从 5:00 到 6:00),第二周重叠为 5 小时(从 0:00 到 5:00 )

第三个没有重叠,所以 0 小时。

这可以在 R 中完成吗?

谢谢 纳加拉吉


df1 <- structure(list(ID = c("ABC123", "XYZ123", "XYZ456"), Start_Date_Time = structure(c(1546675200, 
        1546722000, 1546945200), class = c("POSIXct", "POSIXt"), tzone = ""), 
        End_Date_Time = structure(c(1546862400, 1547326800, 1547352000
        ), class = c("POSIXct", "POSIXt"), tzone = "")), row.names = c(NA, 
            -3L), class = "data.frame")

df2 <- structure(list(ID = c("ABC123", "XYZ123", "XYZ456"), Day = c("Saturday", 
        "Sunday", "Tuesday"), StartTime = c("13:00", "0:00", "0:00"), 
        EndTime = c("18:00", "6:00", "12:00")), row.names = c(NA, 
            -3L), class = "data.frame")

【问题讨论】:

    标签: r date datetime timestamp


    【解决方案1】:

    使用data.table的选项:

    library(data.table)
    setDT(df1)
    setDT(df2)
    fmt <- "%Y-%m-%d %H:%M"
    
    #generate all hours with df2
    DT <- df1[, {
        x <- seq(min(as.IDate(Start_Date_Time)), max(as.IDate(End_Date_Time)), by="1 day")
        .(Date=x, Day=weekdays(x))
        }][
            df2, on=.(Day), nomatch=0L]
    hoursDT <- DT[, .(ID, END_HR=seq.POSIXt(as.POSIXct(paste(Date, StartTime), format=fmt) + 60*60,
            as.POSIXct(paste(Date, EndTime), format=fmt),
            by="1 hour")), 
        seq_len(nrow(DT))]
    
    #count number of overlapping hours by joining the prev data.table with df1
    df1[, Timeline_Hours := 
        hoursDT[.SD, on=.(ID, END_HR>Start_Date_Time, END_HR<=End_Date_Time), by=.EACHI, .N]$N
    ]
    

    df1 的输出:

           ID     Start_Date_Time       End_Date_Time Timeline_Hours
    1: ABC123 2019-01-05 16:00:00 2019-01-07 20:00:00              2
    2: XYZ123 2019-01-06 05:00:00 2019-01-13 05:00:00              6
    3: XYZ456 2019-01-08 19:00:00 2019-01-13 12:00:00              0
    

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多