我有一个这样的数据框。我想找到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分钟
答案 0 :(得分:1)
这是您的问题的一种data.table
方法。
它使用data.table::rleid()
根据条件v1 or v2 > 110
创建组。然后,通过从每个组的最后一个时间戳减去每个组的第一个时间戳,总结在此条件有效的行上。这样会导致按组列出的扩散时间的duration
列。
或者,您可以计算所有持续时间的总和。 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