применить условие, если val для непрерывных минут - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть эти данные:

library(tidyverse)
library(lubridate)

dates <- c("01/01/18 1:00:00 PM" ,"01/01/18 1:01:00 PM",
           "01/01/18 1:02:00 PM" ,"01/01/18 1:03:00 PM",
           "01/01/18 1:04:00 PM" ,"01/01/18 1:05:00 PM",
           "01/01/18 1:06:00 PM" ,"01/01/18 1:07:00 PM",
           "01/01/18 1:08:00 PM" ,"01/01/18 1:09:00 PM",
           "01/01/18 1:10:00 PM" ,"01/01/18 1:11:00 PM")

vals <- c(1, 2, 3, 3, 15, 16, 17, 18, 1, 2, 1, 22)

datfr <- data.frame(dates, vals)

datfr$dates <- dmy_hms(datfr$dates)

Я хочу применить условие:

if the val is < 4 for 2 continuous minutes period then true

Я пытался:

datfr$gr <- datfr %>%
       group_by(by2min = cut(dates, "2 min")) %>%
       summarise(cond = (vals < 4))

но это дает мне:

column cond must be length 1 not 2

и я не уверен в подходе.

Итак, мой ожидаемый результат:

dates                   vals     cond

1 2018-01-01 13:00:00     1      
2 2018-01-01 13:01:00     2      
3 2018-01-01 13:02:00     3      TRUE
4 2018-01-01 13:03:00     3     
5 2018-01-01 13:04:00    15      FALSE
6 2018-01-01 13:05:00    16     
7 2018-01-01 13:06:00    17      FALSE
8 2018-01-01 13:07:00    18      
9 2018-01-01 13:08:00     1      FALSE
10 2018-01-01 13:09:00    2      
11 2018-01-01 13:10:00    1      TRUE
12 2018-01-01 13:11:00   22      

Следовательно, если в течение 2 непрерывных минут значение <4, то истина. </p>

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Предположим, что ваши данные представлены в формате, где разница во времени составляет 1 минуту между записями строк

datfr$cond<-
zoo::rollapply(data = datfr$vals, width = 3, FUN = function(x) { if (all(x < 4)) return(TRUE) else return(FALSE) }, align = "right", fill = FALSE)

Результат:

#                 dates vals  cond
#1  2018-01-01 13:00:00    1 FALSE
#2  2018-01-01 13:01:00    2 FALSE
#3  2018-01-01 13:02:00    3  TRUE
#4  2018-01-01 13:03:00    3  TRUE
#5  2018-01-01 13:04:00   15 FALSE
#6  2018-01-01 13:05:00   16 FALSE
#7  2018-01-01 13:06:00   17 FALSE
#8  2018-01-01 13:07:00   18 FALSE
#9  2018-01-01 13:08:00    1 FALSE
#10 2018-01-01 13:09:00    2 FALSE
#11 2018-01-01 13:10:00    1  TRUE
#12 2018-01-01 13:11:00   22 FALSE
0 голосов
/ 27 ноября 2018

Я пытался просто воспроизвести желаемый результат как можно ближе.Я предполагаю, что пустые элементы cond равны NA s.В случае, если cond является переменной character, а пустые элементы представляют \s, легко настроить вывод, добавив дополнительные mutate(cond = coalesce(as.character(cond), "")).Мне не удалось преобразовать последнее значение в \s/NA.

#library(tidyverse)

datfr %>%
  arrange(dates) %>%
  group_by(by2min = lag(cut(c(min(dates), dates), "2 min"))[-1]) %>%
  mutate(dates = max(dates)) %>%
  group_by(dates) %>%
  summarise(cond = all(vals < 4), vals = last(vals)) %>%
  right_join(datfr, by = c('dates', 'vals')) %>%
  select(dates, vals, cond)

# # A tibble: 12 x 3
#   dates                vals cond 
#   <dttm>              <dbl> <lgl>
# 1 2018-01-01 13:00:00     1 NA   
# 2 2018-01-01 13:01:00     2 NA   
# 3 2018-01-01 13:02:00     3 TRUE 
# 4 2018-01-01 13:03:00     3 NA   
# 5 2018-01-01 13:04:00    15 FALSE
# 6 2018-01-01 13:05:00    16 NA   
# 7 2018-01-01 13:06:00    17 FALSE
# 8 2018-01-01 13:07:00    18 NA   
# 9 2018-01-01 13:08:00     1 FALSE
#10 2018-01-01 13:09:00     2 NA   
#11 2018-01-01 13:10:00     1 TRUE 
#12 2018-01-01 13:11:00    22 FALSE 
0 голосов
/ 27 ноября 2018

Как насчет использования rollapply?

zoo::rollapply(datfr$vals, 3, by = 1, function(x) sum(x<4) == 2)

Редактировать: упрощенная функция

...