【问题标题】:getting total duration based on continuous occurrence of a condition in R dataframe根据 R 数据框中条件的连续出现获取总持续时间
【发布时间】:2019-11-14 03:12:18
【问题描述】:

我有一个这样的数据框。我想找到 v1 或 v2 的持续时间高于 110。

timestamp              v1     v2
    14-05-2019 04:28    112.2   111.0
    14-05-2019 04:30    112.2   110.9
    14-05-2019 04:39    101.4   101.8
    14-05-2019 04:40    108.0   108.8
    14-05-2019 04:45    101.1   101.5
    14-05-2019 04:46    100.8   101.2
    14-05-2019 05:32    111.6   111.5
    14-05-2019 05:36    111.5   111.5
    14-05-2019 05:39    111.5   111.5
    14-05-2019 05:41    111.5   111.5
    14-05-2019 05:46    111.5   111.4
    14-05-2019 05:46    111.5   111.3
    14-05-2019 05:47    111.5   111.3
    14-05-2019 05:51    111.2   111.2
    14-05-2019 05:56    111.2   111.2
    14-05-2019 05:57    111.2   111.2

我的代码:

str = 0
end = 0
dur = 0
diff = 0
for (i in (1:norws(x))) {
  if((x['v1'][i,] >=110) || (x['v2'][i,] >=110)){
    if((str !=0) && (i-str == 1)){
      str = i}else{
        str = i
        end = i - 1
      }}
  if((str<end) && (end != 0)){
    diff =  as.numeric(x[end,1] - x[str,1],units="mins")
    dur = dur + diff
  }}
print(dur)

我想获取 v1 或 v2 大于 110 的连续数据的持续时间。另外,如果 开始和结束都相同,它们不被考虑或差异为0秒。 我会在这里买两套:

14-05-2019 04:28    112.2   111.0
14-05-2019 04:30    112.2   110.9

这里的时间是 2 分钟 14-05-2019 04:30 - 14-05-2019 04:28 同样,

14-05-2019 05:32    111.6   111.5
14-05-2019 05:36    111.5   111.5
14-05-2019 05:39    111.5   111.5
14-05-2019 05:41    111.5   111.5
14-05-2019 05:46    111.5   111.4
14-05-2019 05:46    111.5   111.3
14-05-2019 05:47    111.5   111.3
14-05-2019 05:51    111.2   111.2
14-05-2019 05:56    111.2   111.2
14-05-2019 05:57    111.2   111.2

这里的时间是 25 分钟。即,14-05-2019 05:57 - 14-05-2019 05:32 所以,我总共得到:27 分钟

【问题讨论】:

    标签: r dataframe datetime rstudio


    【解决方案1】:

    这是您的问题的data.table 方法。

    它使用data.table::rleid() 根据条件v1 or v2 &gt; 110 创建组。然后,它通过从每个组的最后一个时间戳中减去每个组的第一个时间戳来总结此条件有效的第 thw 行。这会产生一个列 duration 的 difftimes by group。

    或者,您可以计算所有持续时间的总和。 format() 用于将答案输出为字符串,而不是 difftime。

    样本数据

    library(data.table)
    DT <- fread("timestamp              v1     v2
    14-05-2019T04:28    112.2   111.0
    14-05-2019T04:30    112.2   110.9
    14-05-2019T04:39    101.4   101.8
    14-05-2019T04:40    108.0   108.8
    14-05-2019T04:45    101.1   101.5
    14-05-2019T04:46    100.8   101.2
    14-05-2019T05:32    111.6   111.5
    14-05-2019T05:36    111.5   111.5
    14-05-2019T05:39    111.5   111.5
    14-05-2019T05:41    111.5   111.5
    14-05-2019T05:46    111.5   111.4
    14-05-2019T05:46    111.5   111.3
    14-05-2019T05:47    111.5   111.3
    14-05-2019T05:51    111.2   111.2
    14-05-2019T05:56    111.2   111.2
    14-05-2019T05:57    111.2   111.2")
    
    #create timestamps
    DT[, timestamp := as.POSIXct( timestamp, format = "%d-%m-%YT%H:%M" )]
    

    代码

    #create groups based on v1|v2 > 110
    DT[, group_id := rleid( v1 > 110 | v2 > 110 ) ][]
    #group by group_id, only on rows where v1 or v2 > 110
    DT[ v1 > 110 | v2 > 110, ][, .(duration = max(timestamp) - min(timestamp) ), by = .(group_id)]
    

    输出

    #    group_id duration
    # 1:        1   2 mins
    # 2:        3  25 mins
    

    替代摘要

    将最后一行代码替换为:

    format( 
      sum( 
        DT[ v1 > 110 | v2 > 110, ][, .(duration = max(timestamp) - min(timestamp) ), by = .(group_id)]$duration 
      )
    )
    

    给出所有“组”的总数。

    #27 mins
    

    根据评论中的问题更新

    要包括每个时期的开始和结束,请使用:

    DT[ v1 > 110 | v2 > 110, ][, .(start = min(timestamp),
                                   end = max(timestamp),
                                   duration = max(timestamp) - min(timestamp) ), 
                               by = .(group_id)][,group_id := NULL]
    
    #                  start                 end duration
    # 1: 2019-05-14 04:28:00 2019-05-14 04:30:00   2 mins
    # 2: 2019-05-14 05:32:00 2019-05-14 05:57:00  25 mins
    

    【讨论】:

    • 还有,如何获取分钟的累计总和并显示每个开始日期和结束日期而不是groupid?
    • 在减法之前将时间戳转换为数字,或阅读?difftime
    • DT[, group_id := rleid( v1 > 110 | v2 > 110 ) ][] 未显示所有条件。如果我选择 >95 我应该得到很多,但我只得到 3 件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多