用前后值的平均值填充NA值

时间:2020-02-24 23:21:16

标签: r replace interpolation na

我正在处理一个缺少一些值的天气变量(温度,降水等)数据集。由于采用了特定的方法(将这些变量在几天之内累加),因此需要处理数据集中的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 个答案:

答案 0 :(得分:2)

如何使用approx用内插值替换NA;默认情况下,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在评论中(感谢@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 :(得分:2)

如果要使用最新的非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)]