получение общей продолжительности на основе постоянного возникновения условия в R-кадре данных - PullRequest
0 голосов
/ 03 июля 2019

У меня есть такой фрейм данных.Я хочу найти продолжительность, для которой 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 минут

1 Ответ

1 голос
/ 03 июля 2019

Вот подход 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...