Использование R для создания вектора, содержащего непрерывные отсчеты на основе даты и времени - PullRequest
0 голосов
/ 02 октября 2018

У меня есть кадр данных в R, который выглядит следующим образом ...

Year  Month  Day  Hour DateTime 
1950  1      4    12   1/4/1950 12:00
1950  1      4    13   1/4/1950 13:00
1950  1      4    14   1/4/1950 14:00
1950  1      4    15   1/4/1950 15:00
1950  1      4    18   1/4/1950 18:00
1950  1      4    21   1/4/1950 21:00
1950  1      4    22   1/4/1950 22:00
1950  1      5    23   1/5/1950 23:00

Данные идут с года (1950-2017) с месяцами (1-12) дня (1-31) час(0-23), и я хочу создать вектор, который суммирует наблюдения, которые являются непрерывными, то есть наблюдения, которые следуют друг за другом.Например, первые несколько чисел в векторе созданного столбца должны быть (4,1,3), поскольку первые четыре наблюдения являются непрерывными, а следующие - нет, затем следующие три являются непрерывными.

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Мы можем использовать tidyverse инструменты и cumsum, чтобы создать групповые индексы для последовательных прогонов, а затем получить количество строк в каждой группе.Обратите внимание, что я не воспроизводил ожидаемый результат, поскольку последняя строка не является последовательной от второй до последней строки в ваших данных.

library(tidyverse)
library(lubridate)

tbl <- read_table2(
"Year  Month  Day  Hour
1950  1      4    12
1950  1      4    13
1950  1      4    14
1950  1      4    15
1950  1      4    18
1950  1      4    21
1950  1      4    22
1950  1      5    23"
)
tbl %>%
  mutate(
    dt = str_c(Year, Month, Day, Hour, sep = "-") %>% ymd_h(),
    consec_grp = cumsum(dt - lag(dt, default = 0) != hours(1))
  ) %>%
  group_by(consec_grp) %>%
  mutate(consec_num = n())
#> # A tibble: 8 x 7
#> # Groups:   consec_grp [4]
#>    Year Month   Day  Hour dt                  consec_grp consec_num
#>   <int> <int> <int> <int> <dttm>                   <int>      <int>
#> 1  1950     1     4    12 1950-01-04 12:00:00          1          4
#> 2  1950     1     4    13 1950-01-04 13:00:00          1          4
#> 3  1950     1     4    14 1950-01-04 14:00:00          1          4
#> 4  1950     1     4    15 1950-01-04 15:00:00          1          4
#> 5  1950     1     4    18 1950-01-04 18:00:00          2          1
#> 6  1950     1     4    21 1950-01-04 21:00:00          3          2
#> 7  1950     1     4    22 1950-01-04 22:00:00          3          2
#> 8  1950     1     5    23 1950-01-05 23:00:00          4          1

Создано в 2018-10-02 с помощью представпакет (v0.2.0).

0 голосов
/ 02 октября 2018

Мы проверяем разницу между соседними датами с помощью difftime, проверяем, не равна ли разница 1, используем rle, чтобы получить счет

dt <- as.POSIXct(df1$DateTime, format = "%m/%d/%Y %H:%M")
rle(cumsum(c(TRUE, difftime(dt[-1], dt[-length(dt)], unit = "hour") != 1)))$lengths
#[1] 4 1 2 1

Или, как упомянул @Ryan, *Также можно использовать 1006 *

rle(cumsum(c(TRUE, diff(dt, unit = "hour") != 1)))$lengths

data

df1 <- structure(list(Year = c(1950L, 1950L, 1950L, 1950L, 1950L, 1950L, 
1950L, 1950L), Month = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), Day = c(4L, 
4L, 4L, 4L, 4L, 4L, 4L, 5L), Hour = c(12L, 13L, 14L, 15L, 18L, 
21L, 22L, 23L), DateTime = c("1/4/1950 12:00", "1/4/1950 13:00", 
"1/4/1950 14:00", "1/4/1950 15:00", "1/4/1950 18:00", "1/4/1950 21:00", 
"1/4/1950 22:00", "1/5/1950 23:00")), class = "data.frame", row.names = c(NA, 
 -8L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...