Как рассчитать период времени до соответствия условия - PullRequest
1 голос
/ 02 апреля 2020

Мне нужно рассчитать время последовательных дат, пока разница во времени между двумя последовательными датами не превысит 13 секунд.

Например, во фрейме данных, созданном с кодом, показанным ниже, тест столбца имеет разницу во времени между датами. Что мне нужно, так это события времени между строками с тестом> 13 секунд.

# Create a vector of dates with a random time difference in seconds between records
dates <- seq(as.POSIXct("2020-01-01 00:00:02"), as.POSIXct("2020-01-02 00:00:02"), by = "2 sec")
dates <- dates + sample(15, length(dates), replace = T)

# Create a data.frame
data <- data.frame(id = 1:length(dates), dates = dates)

# Create a test field with the time difference between each date and the next
data$test <- c(diff(data$dates, lag = 1), 0)

# Delete the zero and negative time
data <- data[data$test > 0, ]

head(data)

То, что я хочу, выглядит примерно так:

enter image description here

1 Ответ

1 голос
/ 02 апреля 2020

Чтобы получить желаемый результат, нам нужно определить «блоки» наблюдения. Каждый блок разбивается, где test больше 13.
Мы начинаем идентифицировать split_point, а затем с помощью функции rle мы можем присвоить идентификатор каждому блоку. Затем мы можем отфильтровать split_point и суммировать оставшиеся блоки. Один раз с суммой секунд, затем с минимальной датой событий.

split_point <- data$test <=13
# Find continuous blocks
block_str <- rle(split_point)
# Create block IDs
data$block <- rep(seq_along(block_str$lengths), block_str$lengths)
data <- data[split_point, ] # Remove split points

# Summarize
final_df <- aggregate(test ~ block, data = data, FUN = sum)
dtevent <- aggregate(dates ~ block, data= data, FUN=min)

# Join the two summaries
final_df$DatetimeEvent <- dtevent$dates

head(final_df)
#>   block test       DatetimeEvent
#> 1     1 101  2020-01-01 00:00:09
#> 2     3 105  2020-01-01 00:01:11
#> 3     5 277  2020-01-01 00:02:26
#> 4     7  46  2020-01-01 00:04:58
#> 5     9  27  2020-01-01 00:05:30
#> 6    11 194  2020-01-01 00:05:44

Создано в 2020-04-02 пакетом Представить (v0.3.0)

Использование dplyr для удобства:

library(dplyr)

final_df <- data %>%
  mutate(split_point = test <= 13,
         block = with(rle(split_point), rep(seq_along(lengths), lengths))) %>%
  group_by(block) %>%
  filter(split_point) %>%
  summarise(DateTimeEvent = min(dates), TotalTime = sum(test))

final_df
#> # A tibble: 1,110 x 3
#>    block DateTimeEvent       TotalTime
#>    <int> <dttm>              <drtn>   
#>  1     1 2020-01-01 00:00:06 260 secs 
#>  2     3 2020-01-01 00:02:28 170 secs 
#>  3     5 2020-01-01 00:04:11 528 secs 
#>  4     7 2020-01-01 00:09:07  89 secs 
#>  5     9 2020-01-01 00:10:07  37 secs 
#>  6    11 2020-01-01 00:10:39 135 secs 
#>  7    13 2020-01-01 00:11:56  50 secs 
#>  8    15 2020-01-01 00:12:32 124 secs 
#>  9    17 2020-01-01 00:13:52  98 secs 
#> 10    19 2020-01-01 00:14:47  83 secs 
#> # … with 1,100 more rows

Создано в 2020-04-02 пакетом prex (v0.3.0 )

(результаты отличаются, потому что reprex воссоздает данные каждый раз)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...