Среднее за определенный период времени в R - PullRequest
0 голосов
/ 04 августа 2020

У меня есть почасовые данные о значениях CO2, и я хотел бы знать, какова концентрация CO2 в ночное время (например, с 21:00 до 7:00). Воспроизводимый пример:

library(tidyverse); library(lubridate)

times <- seq(ymd_hms("2020-01-01 08:00:00"),
ymd_hms("2020-01-04 08:00:00"),  by = "1 hours")
values <- runif(length(times), 1, 15)
df <- tibble(times, values)

Как получить средние ночные значения (например, между 21:00 и 7:00)? Конечно, я могу фильтровать следующим образом:

df <- df %>% 
filter(!hour(times) %in% c(8:20))

И затем давать идентификатор каждому наблюдению в течение ночи

df$ID <- rep(LETTERS[1:round(nrow(df)/11)], 
times = 1, each = 11)

И, наконец, группировать и суммировать

df_grouped <- df %>% 
group_by(., ID) %>%
summarise(value_mean =mean(values))

Но я уверен, что это не лучший способ. Как это лучше сделать? Особенно та часть, где мы даем ID ночным значениям

1 Ответ

1 голос
/ 04 августа 2020

Вы можете использовать data.table::frollmean, чтобы получить средства для определенного времени окна. В вашем случае вам нужны средние значения за последние 10 часов, поэтому мы устанавливаем аргумент функции n равным 10:

> df$means <- data.table::frollmean(df$values, 10)
> df
> head(df, 20)
# A tibble: 20 x 3
   times               values means
   <dttm>               <dbl> <dbl>
 1 2020-01-01 08:00:00   4.15 NA   
 2 2020-01-01 09:00:00   6.24 NA   
 3 2020-01-01 10:00:00   5.17 NA   
 4 2020-01-01 11:00:00   9.20 NA   
 5 2020-01-01 12:00:00  12.3  NA   
 6 2020-01-01 13:00:00   2.93 NA   
 7 2020-01-01 14:00:00   9.12 NA   
 8 2020-01-01 15:00:00   9.72 NA   
 9 2020-01-01 16:00:00  12.0  NA   
10 2020-01-01 17:00:00  13.4   8.41
11 2020-01-01 18:00:00  10.2   9.01
12 2020-01-01 19:00:00   1.97  8.59
13 2020-01-01 20:00:00  11.9   9.26
14 2020-01-01 21:00:00   8.84  9.23
15 2020-01-01 22:00:00  10.1   9.01
16 2020-01-01 23:00:00   3.76  9.09
17 2020-01-02 00:00:00   9.98  9.18
18 2020-01-02 01:00:00   5.56  8.76
19 2020-01-02 02:00:00   5.22  8.09
20 2020-01-02 03:00:00   6.36  7.39

Каждая строка в среднем столбце будет средним значением того же столбца значений строки с 9 последними строками столбца значений. Конечно, будут некоторые НА.

Возможно, вам стоит взглянуть на пакет tsibble, созданный для управления временными рядами. должны быть равномерно распределены в ваших данных, чтобы использовать это решение:

n <- diff(which(grepl('20:00:00|08:00:00', df$times))) + 1
n <- unique(n)
df$means <- data.table::frollmean(df$values, n)

> head(df, 20)
# A tibble: 20 x 3
   times               values means
   <dttm>               <dbl> <dbl>
 1 2020-01-01 08:00:00  11.4  NA   
 2 2020-01-01 09:00:00   7.03 NA   
 3 2020-01-01 10:00:00   7.15 NA   
 4 2020-01-01 11:00:00   6.91 NA   
 5 2020-01-01 12:00:00   8.18 NA   
 6 2020-01-01 13:00:00   4.70 NA   
 7 2020-01-01 14:00:00  13.8  NA   
 8 2020-01-01 15:00:00   5.16 NA   
 9 2020-01-01 16:00:00  12.3  NA   
10 2020-01-01 17:00:00   3.81 NA   
11 2020-01-01 18:00:00   3.09 NA   
12 2020-01-01 19:00:00   9.89 NA   
13 2020-01-01 20:00:00   1.24  7.28
14 2020-01-01 21:00:00   8.07  7.02
15 2020-01-01 22:00:00   5.59  6.91
16 2020-01-01 23:00:00   5.77  6.81
17 2020-01-02 00:00:00  10.7   7.10
18 2020-01-02 01:00:00   3.44  6.73
19 2020-01-02 02:00:00  10.3   7.16
20 2020-01-02 03:00:00   4.61  6.45
...