Как извлечь несколько 5-минутных средних значений из кадра данных на основе указанного времени начала?

У меня есть посекундные данные для каналов A, B и C, как показано ниже (здесь показаны только первые 6 строк):

                 date        A        B        C
1 2020-03-06 09:55:42 224.3763 222.3763 226.3763
2 2020-03-06 09:55:43 224.2221 222.2221 226.2221
3 2020-03-06 09:55:44 224.2239 222.2239 226.2239
4 2020-03-06 09:55:45 224.2044 222.2044 226.2044
5 2020-03-06 09:55:46 224.2397 222.2397 226.2397
6 2020-03-06 09:55:47 224.3690 222.3690 226.3690

Я хотел бы иметь возможность извлекать несколько 5-минутных средних значений для столбцов A, B и C на основе времени простоя. Есть ли способ сделать это, когда мне нужно было бы вводить только начальный период времени, вместо того, чтобы вводить начальное И конечное время для каждого периода времени, который я хочу извлечь? По сути, я хочу иметь возможность вводить время начала, а мой код вычисляет и извлекает среднее значение за последующие 5 минут.

Ранее я использовал функцию time.average из пакета openair для получения 1-минутных средних значений для всего набора данных. Затем я создал вектор с начальным временем, а затем использовал функцию «подмножества» для извлечения интересующих меня средних значений за 1 минуту.

library(openair)
df.avg <- timeAverage(df, avg.time = "min", statistic = "mean")
cond.1.time <- c(
  '2020-03-06 10:09:00', 
  '2020-03-06 10:13:00',
  '2020-03-06 10:18:00',
) #enter start times
library(dplyr)
df.cond.1.avg <- subset(df.avg,
                           date %in% cond.1.time)  #filter data based off vector
df.cond.1.avg <- as.data.frame(df.cond.1.avg) #tibble to df

Однако этот подход не будет работать для 5-минутных средних значений, поскольку не все интересующие меня временные рамки начинаются с 5-минутного приращения друг к другу. Кроме того, мой предыдущий подход вынудил меня использовать только 1-минутные средние значения, которые начинаются в верхней части минуты.

Мне нужно извлекать 5-минутные средние значения, случайным образом разбросанные в течение дня. Это не скользящие средние. Мне нужно будет извлекать примерно тридцать 5-минутных средних значений в день, поэтому возможность вводить только дату начала была бы ключевой.

Спасибо!


person lawrence of 'R'abia    schedule 24.07.2020    source источник


Ответы (1)


Используя библиотеки dplyr и tidyr, интервал для усреднения можно выбрать путем фильтрации дат и усреднения. Это не кажется эффективным, но может вам помочь.

library(dplyr)
library(tidyr)
data <- data.frame(date = seq(as.POSIXct("2020-02-01 01:01:01"),
                              as.POSIXct("2020-02-01 20:01:10"),
                              by = "sec"),
                   A = rnorm(68410),
                   B = rnorm(68410),
                   C = rnorm(68410))

meanMinutes <- function(data, start, interval){
  # Interval in minutes
  start <- as.POSIXct(start)
  end <- start + 60*interval
  filterData <- dplyr::filter(data, date <= end, date >= start)
  date_start <- filterData$date[1]
  meanData <- filterData %>% 
    tidyr::gather(key = "param", value = "value", A:C) %>% 
    dplyr::group_by(param) %>% 
    dplyr::summarise(value = mean(value, na.rm = T)) %>% 
    tidyr::spread(key = "param", value = "value")
  return(cbind(date_start, meanData))
}

На одно свидание

meanMinutes(data, "2020-02-01 07:03:11", 5)

Результат:

           date_start           A           B          C
1 2020-02-01 07:03:11 0.004083064 -0.06067075 -0.1304691

Для нескольких дат:

dates <- c("2020-02-01 02:53:41", "2020-02-01 05:23:14", 
           "2020-02-01 07:03:11", "2020-02-01 19:10:45")
do.call(rbind, lapply(dates, function(x) meanMinutes(data, x, 5)))

Результат:

           date_start            A           B           C
1 2020-02-01 02:53:41 -0.001929374 -0.03807152  0.06072332
2 2020-02-01 05:23:14  0.009494321 -0.05911055 -0.02698245
3 2020-02-01 07:03:11  0.004083064 -0.06067075 -0.13046909
4 2020-02-01 19:10:45 -0.123574816 -0.02373881  0.05997007
person Novvier    schedule 27.07.2020
comment
Спасибо! Это прекрасно работает! Есть ли простой способ использовать это, чтобы также получить стандартные отклонения для тех же 5-минутных периодов? Я знаю, что могу перезапустить код и изменить значение «value = mean ()» на «value = sd ()», а затем выполнить cbind для их объединения. Но можно ли манипулировать кодом, чтобы получить как среднее значение, так и стандартное отклонение за один раз? - person lawrence of 'R'abia; 27.07.2020
comment
Да, изменение в резюме: dplyr::summarise(Mean = mean(value), SD = sd(value) %>% tidyr::gather(key = "stat", value = "value", 2:3) %>% - person Novvier; 29.07.2020