Как вырезать две последовательности Posixct с использованием предопределенных уровней

#r #dplyr #posixct

#r #dplyr #posixct

Вопрос:

Мне нужно объединить две 5-минутные последовательности POSIXct в 10-минутные последовательности. Для этого я хочу создать 10-минутный ключ из обеих 5-минутных последовательностей, чтобы оба использовали одинаковые уровни.

Мне интересно, есть ли R-способ сделать это?

Вот пример:

 a = seq(as.POSIXct("2012-06-01 06:01"), by = "5 min", length.out = 24)
b = seq(as.POSIXct("2012-06-01 06:07"), by = "5 min", length.out = 24)

cut(a, "10 min")
cut(b, "10 min")
 

Вы заметите, что seq a и b используют разные уровни

Теперь вы можете сделать некоторые хитрости, чтобы исправить это, но это не очень приятно

 b_adjusted = b-min(abs(min(as.POSIXct(cut(a, "10 min")))-b))
cut(b_adjusted, "10 min")
 

или

 keys = cut(c(a,b), "10 min")
a = keys[1:length(a)]
b = keys[(length(a) 1):(length(a) length(b))]
 

Это всего лишь пример, в моем реальном случае задействовано> 10 последовательностей.
В идеале я мог бы использовать cut с уровнями, начиная с первого раунда 10-минутного уровня, например, если первый элемент в моей последовательности равен 00: 17, тогда сгенерированный ключ равен 00: 10

Ответ №1:

Возможно, объединить все векторы, а затем сгенерировать 10-минутную последовательность от min значения до max значения.

 library(lubridate)

combined_seq <- c(a, b)
lvls <- seq(floor_date(min(combined_seq), '10 mins'),
              ceiling_date(max(combined_seq), '10 mins'), by = '10 mins')
 

Затем вы можете использовать это lvls как уровни cut .

 cut(a, levels)
cut(b, levels)
 

Ответ №2:

Используя базу R, мы формируем список входных данных, L , и вычисляем L10 из него список векторов, которые, как мы видим, имеют общие наборы значений, если мы используем данные в вопросе; однако, если это не общий случай, мы можем создать levs из них набор уровней, дающий список факторовс L10f общими уровнями.

 min10.POSIXct <- function(x) {  # returns POSIXct arg truncated to 10 min
  as.POSIXct(600 * floor(as.numeric(a) %/% 600), origin = "1970-01-01")
}
L <- list(a, b)
L10 <- lapply(L, min10.POSIXct)

# empty result shows they have same values
length(setdiff(L10[[1]], L10[[2]]))
## [1] 0

rng <- range(do.call("range", L10))
levs <- format(seq(rng[1], rng[2], "10 min"))

L10f <- lapply(L10, factor, levs)
 

Обновить

Несколько раз пересматривал.