заполнить значения NA средними значениями предыдущих и последующих значений - PullRequest
1 голос
/ 25 февраля 2020

Я работаю с набором переменных погоды (температура, осадки и т. Д. c.), У которых есть несколько пропущенных значений. Из-за моего конкретного подхода c (суммирование этих переменных за несколько дней) мне нужно обратиться к значениям NA в наборе данных.

Когда есть пропущенное дневное значение, я бы хотел заполнить этот день среднее значение предыдущего и следующего дня. Здесь предполагается, что значения погоды схожи от одного дня к другому. И да, я понимаю, что это большое предположение.

Я разработал следующее:

maxTemp <- c(13.2, 10.7, NA, 17.9, 6.6, 10, 13, NA, NA, 8.8, 9.9, 14.9, 16.3, NA, 18, 9.9, 11.5, 15.3, 21.7, 23.9, 26.6, 27, 22.3, NA, 17.9)
weather <- as.data.frame(maxTemp)
weather %>% 
  mutate(maxTempNA = if_else(is.na(maxTemp),
                             (lag(maxTemp) + lead(maxTemp))/2,
                             maxTemp))

Однако в некоторых случаях у меня есть два значения NA в последовательные дни, поэтому это не работает Есть какие-нибудь мысли о подходах, позволяющих кодировать это так, чтобы при наличии двух (или более) NA в среднем усредненные значения использовались для заполнения NA?

Окончательный результат будет выглядеть примерно так:

maxTemp <- c(13.2, 10.7, 14.3, 17.9, 6.6, 10, 13, 10.9, 10.9, 8.8, 9.9, 14.9, 16.3, 17.15, 18, 9.9, 11.5, 15.3, 21.7, 23.9, 26.6, 27, 22.3, 20.1, 17.9)

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Как насчет использования approx для замены NA s интерполированными значениями; по умолчанию approx использует линейную интерполяцию, поэтому она должна соответствовать вашим результатам замены вручную по среднему значению.

weather %>%
    mutate(maxTemp_interp = approx(1:n(), maxTemp, 1:n())$y)
#    maxTemp maxTemp_interp
# 1     13.2          13.20
# 2     10.7          10.70
# 3       NA          14.30
# 4     17.9          17.90
# 5      6.6           6.60
# 6     10.0          10.00
# 7     13.0          13.00
# 8       NA          11.60
# 9       NA          10.20
# 10     8.8           8.80
# 11     9.9           9.90
# 12    14.9          14.90
# 13    16.3          16.30
# 14      NA          17.15
# 15    18.0          18.00
# 16     9.9           9.90
# 17    11.5          11.50
# 18    15.3          15.30
# 19    21.7          21.70
# 20    23.9          23.90
# 21    26.6          26.60
# 22    27.0          27.00
# 23    22.3          22.30
# 24      NA          20.10
# 25    17.9          17.90

Я создал новый столбец, чтобы было легче сравнивать его с исходными данными. .


Обновление

В комментариях Маркус указал (спасибо @markus), что для воспроизведения ожидаемого результата вам действительно понадобится method = "constant" с f = 0.5:

weather %>%
    mutate(maxTemp_interp = approx(1:n(), maxTemp, 1:n(), method = "constant", f = 0.5)$y)
#    maxTemp maxTemp_interp
# 1     13.2          13.20
# 2     10.7          10.70
# 3       NA          14.30
# 4     17.9          17.90
# 5      6.6           6.60
# 6     10.0          10.00
# 7     13.0          13.00
# 8       NA          10.90
# 9       NA          10.90
# 10     8.8           8.80
# 11     9.9           9.90
# 12    14.9          14.90
# 13    16.3          16.30
# 14      NA          17.15
# 15    18.0          18.00
# 16     9.9           9.90
# 17    11.5          11.50
# 18    15.3          15.30
# 19    21.7          21.70
# 20    23.9          23.90
# 21    26.6          26.60
# 22    27.0          27.00
# 23    22.3          22.30
# 24      NA          20.10
# 25    17.9          17.90
1 голос
/ 25 февраля 2020

Если вы хотите использовать среднее значение последнего не-NA значения, идущего вперед и назад, вы можете использовать что-то вроде data.table::nafill(), чтобы заполнить значения как вниз, так и вверх, а затем взять среднее значение:

weather$prevTemp = data.table::nafill(weather$maxTemp, type = "locf")
weather$nextTemp = data.table::nafill(weather$maxTemp, type = "nocb")
weather$maxTemp[is.na(weather$maxTemp)] = ((weather$prevTemp + weather$nextTemp) / 2)[is.na(weather$maxTemp)]
...