我有一个有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]
这里有一个选择。
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")]
我们可以使用 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")