数据表

问题描述 投票:1回答:1

我有一个有2列的datatable,一个是时间戳,一个是条件。一列是时间戳,一列是条件。我试图找出一个条件发生的持续时间。我能够得到持续时间。但如果我的条件是在两天内,那么我将得到超过24小时和所有。 我需要把它分割成各自的日期。我正在使用 rleid 组,然后我发现duration(max(timestamp) - min(timestamp) 在每个满足条件的组中。然后我终于 aggregate 好日子 sum).

             timestamp  condition
    2020-01-01 10:10:13 0
    2020-01-01 10:11:23 1
    2020-01-01 10:14:45 1
    2020-01-01 11:23:02 1
    2020-01-01 11:33:14 1
    2020-01-01 16:10:13 0
    2020-01-01 18:34:12 1
    2020-01-01 20:10:33 1
    2020-01-01 23:04:56 1
    2020-01-02 10:14:45 1
    2020-01-02 11:23:02 1
    2020-01-02 11:33:14 0
    2020-01-02 16:10:13 0

寻找持续时间,当条件是 1.预期的输出:

Date            Duration
2020-01-01      05:52:35
2020-01-02      11:23:02

当我进行分组和寻找持续时间时,我得到的是什么。

 Date            Duration
2020-01-01      18:10:41

问题出在分组上,因为 rleid 是分组,不分日期。实际上,如果条件是连续两天发生,那么第一天应该限制到23:59:59,第二天从00:00:00开始。这种情况应该发生在任何天数上。

我的代码。

fdata = data[, group_id := rleid(condition == 1)][]
out = fdata[(condition == 1),][,.(start = as.Date(min(timestamp)),
         duration = as.numeric(max(timestamp) - min(timestamp),units='mins')),by = .((group_id)][,group_id := NULL]
r data.table aggregate grouping
1个回答
2
投票

这里有一个选择。

DT[, g := rleid(id, as.IDate(timestamp), condition)][
    condition==1L, duration := as.numeric(timestamp[.N] - timestamp[1L], units='secs'), g]

unique(DT, by="g")[condition==1L & duration > 0, .(Duration=sum(duration)), .(id, date=as.IDate(timestamp))]

另一种方法:

DT[, g := rleid(id, as.IDate(timestamp), condition)][
    condition==1L, .(id=id[1L], date=as.IDate(timestamp)[1L],
        dft=as.numeric(timestamp[.N] - timestamp[1L], units='secs')), g][
            dft > 0, .(Duration==sum(dft)), .(id, date)]

输出:

   id       date Duration
1:  1 2020-01-01    21155
2:  1 2020-01-02     4097

数据。

library(data.table)
DT <- fread("id,timestamp,condition
1,2020-01-01 10:10:13,0
1,2020-01-01 10:11:23,1
1,2020-01-01 10:14:45,1
1,2020-01-01 11:23:02,1
1,2020-01-01 11:33:14,1
1,2020-01-01 16:10:13,0
1,2020-01-01 18:34:12,1
1,2020-01-01 20:10:33,1
1,2020-01-01 23:04:56,1
1,2020-01-02 10:14:45,1
1,2020-01-02 11:23:02,1
1,2020-01-02 11:33:14,0
1,2020-01-02 16:10:13,0")
DT[, timestamp := as.POSIXct(timestamp, format="%Y-%m-%d %T")]

1
投票

我们可以使用 rleid 在 "条件 "栏上

library(data.table)
library(lubridate)
out <- setDT(df1)[,  .(Duration = max(timestamp) - min(timestamp)),
        .(Date = as.IDate(timestamp),
    grp = rleid(condition), condition)
     ][as.logical(condition)][, .(Duration = sum(Duration)), .(Date)]

out[, Duration := seconds_to_period(Duration)][]
#       Date   Duration
#1: 2020-01-01 5H 52M 35S
#2: 2020-01-02  1H 8M 17S

资料

df1 <- structure(list(timestamp = structure(c(1577891413, 1577891483, 
    1577891685, 1577895782, 1577896394, 1577913013, 1577921652, 1577927433, 
    1577937896, 1577978085, 1577982182, 1577982794, 1577999413), class = c("POSIXct", 
    "POSIXt"), tzone = ""), condition = c(0L, 1L, 1L, 1L, 1L, 0L, 
    1L, 1L, 1L, 1L, 1L, 0L, 0L)), row.names = c(NA, -13L), class = "data.frame")
© www.soinside.com 2019 - 2024. All rights reserved.