Среднее из наблюдений в определенные даты с использованием dplyr - PullRequest
0 голосов
/ 20 октября 2018

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

data <- data.frame( date = rep(c(1:10),5), obs = c(1:50) )

, где в одном столбце у меня есть даты, а в другом столбце у меня есть переменная obs.Я хотел бы использовать dplyr для вычисления для каждой строки среднего значения переменной obs для наблюдения в течение 2 дней со значения date, исключая текущую строку date.

Например, для date = 3 в строке 13 Я хочу взять все строки с date, равными 1, 2, 3, 4 и 5, и взять среднее значение obsдля этих строк, исключая значение obs в строке 13.Это даст:

mean(c(1:5, 11, 12, 14, 15, 21:25, 31:35, 41:45))
# 23.41667

, где вы можете видеть, что я взял все наблюдения для дат между 1 и 5, но я пропустил наблюдение для строки 13.

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

data <- data.frame( date = c(rep(c(1:10),5), 3), obs = c(1:51) )

, где дата 3 повторяется дважды, я хотел бы получить следующее среднее значение для наблюдения в строке 13:

mean(c(1:5, 11, 12, 14, 15, 51, 21:25, 31:35, 41:45)) 
# 24.52

и следующее среднее значение для этого в строке 51:

mean(c(1:5, 11:15, 21:25, 31:35, 41:45))
# 23

По сути, для каждой строки я хотел бы получить среднее значение всех other наблюдений в столбце obs, происходящих в пределах 2дни (+ - 2 дня) даты в этой конкретной строке.

Ответы [ 2 ]

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

Использование dplyr:

Решение 1 вычисляет среднее значение на 2 строки ниже и на 2 строки выше фактической даты:

data %>%
  mutate(temp1 = lag(obs, 1), 
         temp2 = lag(obs, 2),
         temp3 = lead(obs, 1),
         temp4 = lead(obs, 2)) %>%
  mutate(mean = rowMeans(cbind(temp1,temp2, temp3, temp4), na.rm = TRUE)) %>%
  select(date, obs, mean)

Решение 2 рассчитывает среднее значение от 2строки ниже и 2 строки выше фактической даты, но с учетом всех вхождений даты:

data %>%
  mutate(temp1 = lag(obs, 1), 
         temp2 = lag(obs, 2),
         temp3 = lead(obs, 1),
         temp4 = lead(obs, 2)) %>%
  group_by(date) %>%
  mutate(n = n(),
         mean = sum(temp1, temp2, temp3, temp4, na.rm = TRUE)/(4*n)) %>%
  ungroup() %>%
  select(date, obs, mean)
0 голосов
/ 20 октября 2018

Если мы хотим получить среднее для 4 значений, то есть 2 значений выше, 2 ниже, исключая значение, используйте цикл

sapply(seq_len(nrow(data)), function(i)
     mean(data$obs[pmax(0, setdiff((i-2):(i+2), i))], na.rm = TRUE))

Или используйте rollapply с partial = TRUE

library(zoo)
library(dplyr)
data %>% 
    mutate(avg = (rollapply(obs, width = 5, FUN = "sum", align = "center", 
        fill = NA, partial = TRUE) - obs)/rep(c(2:4, 3:2), c(1, 1, n()-4, 1, 1))) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...