Фильтровать временные ряды по часам - PullRequest
1 голос
/ 24 апреля 2020

У меня есть ряд данных с данными, которые выглядят так:

2020-01-02 09:30:00 1 gdss
2020-01-02 10:00:00 2 jojo
2020-01-02 10:30:00 3 hutr 
2020-01-02 11:00:00 2 uff
2020-01-02 11:30:00 4 wwe
2020-01-02 12:00:00 1 vev
2020-01-02 12:30:00 2 wow

В нем больше столбцов, но это не важно. Тем не менее, весь набор имеет 30-минутные данные за более чем десятилетие.

Я хотел бы фильтровать определенные часы каждый день, но не могу понять это правильно. Я использую lubridate

Например, чтобы получить этот интервал:

2020-01-02 10:30:00 3 hutr 
2020-01-02 11:00:00 2 uff
2020-01-02 11:30:00 4 wwe
2020-01-02 12:00:00 1 vev

Я пробовал следующее:

with(load_dataset, load_dataset[ (hour(load_dataset$Date) == 10 & minute(load_dataset$Date) == 30) | (hour(load_dataset$Date) == 12 & minute(load_dataset$Date) < 30), ])

Это дает только первый и последний ,

with(load_dataset, load_dataset[(hour(load_dataset$Date) == 10 & minute(load_dataset$Date) == 30) & (hour(load_dataset$Date) == 12 & minute(load_dataset$Date) < 30), ])

Это дает ноль строк.

with(load_dataset, load_dataset[(hour(load_dataset$Date) >= 10 & minute(load_dataset$Date) == 30) & (hour(load_dataset$Date) <= 12 & minute(load_dataset$Date) <= 30), ])

Это дает только интервалы с 30 минутами:

2020-01-02 10:30:00 3 hutr
2020-01-02 11:30:00 4 wwe

Как отфильтровать каждую строку в наборе данных для каждого дня с 10:30 до 12:00, включая 12: 00

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Вы можете указать время до "numeric" и посмотреть, находится ли оно в пределах 1030:1200.

load_dataset[as.numeric(strftime(load_dataset$date, "%H%M")) %in% 1030:1200, ]
#                  date V3   V4
# 3 2020-01-02 10:30:00  3 hutr
# 4 2020-01-02 11:00:00  2  uff
# 5 2020-01-02 11:30:00  4  wwe
# 6 2020-01-02 12:00:00  1  vev

Примечание: Это решение предполагает формат "POSIXct" для столбца date ; если это не так, используйте это раньше:

load_dataset$date <- as.POSIXct(load_dataset$date)

Этот принцип также работает для объектов "реального" временного ряда, таких как "xts".

load_dataset.xts[
  as.numeric(strftime(as.POSIXct(attr(load_dataset.xts, "index"), 
                                 origin="1970-01-01"), "%H%M")) %in% 1030:1200, ]
#                     V3  V4    
# 2020-01-02 10:30:00 "3" "hutr"
# 2020-01-02 11:00:00 "2" "uff" 
# 2020-01-02 11:30:00 "4" "wwe" 
# 2020-01-02 12:00:00 "1" "vev" 

Данные:

load_dataset <- structure(list(date = structure(c(1577953800, 1577955600, 1577957400, 
1577959200, 1577961000, 1577962800, 1577964600), class = c("POSIXct", 
"POSIXt"), tzone = ""), V3 = c(1L, 2L, 3L, 2L, 4L, 1L, 2L), V4 = c("gdss", 
"jojo", "hutr", "uff", "wwe", "vev", "wow")), row.names = c(NA, 
-7L), class = "data.frame")

load_dataset.xts <- structure(c("1", "2", "3", "2", "4", "1", "2", "gdss", "jojo", 
"hutr", "uff", "wwe", "vev", "wow"), .Dim = c(7L, 2L), .Dimnames = list(
    NULL, c("V3", "V4")), index = structure(c(1577953800, 1577955600, 
1577957400, 1577959200, 1577961000, 1577962800, 1577964600), tzone = "", tclass = c("POSIXct", 
"POSIXt")), class = c("xts", "zoo"))
1 голос
/ 24 апреля 2020

Я думаю, что вы пытались сделать:

subset(transform(df, hour = as.integer(format(datetime, "%H")), 
                     minute = as.integer(format(datetime, "%M"))), 
      (hour == 10 & minute >= 30) | hour == 11 | hour == 12 & minute == 0)


#  V3   V4            datetime hour minute
#3  3 hutr 2020-01-02 10:30:00   10     30
#4  2  uff 2020-01-02 11:00:00   11      0
#5  4  wwe 2020-01-02 11:30:00   11     30
#6  1  vev 2020-01-02 12:00:00   12      0

Используя dplyr и lubridate это можно сделать как:

library(dplyr)
library(lubridate)

df %>%
  mutate(hour = hour(datetime), minute = minute(datetime)) %>%
  filter((hour == 10 & minute >= 30) | hour == 11 | hour == 12 & minute == 0)

data

df <-  structure(list(V3 = c(1L, 2L, 3L, 2L, 4L, 1L, 2L), V4 = structure(c(1L, 
3L, 2L, 4L, 7L, 5L, 6L), .Label = c("gdss", "hutr", "jojo", "uff", 
"vev", "wow", "wwe"), class = "factor"), datetime = structure(c(1577957400, 
1577959200, 1577961000, 1577962800, 1577964600, 1577966400, 1577968200
), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, 
-7L), class = "data.frame")
...