6.23 用最后一个非 NA 值填充 NA

6.23.1 问题

你想要将非 NA 值代替向量或者因子中的 NA 值。

6.23.2 方案

这段代码展示了如何填充向量中的空白。如果需要重复执行此操作,请参阅下面的函数。该函数还可以用第一个确定的值填充第一个即为NA的情况,并正确处理因子。

  1. # 示例数据
  2. x <- c(NA, NA, "A", "A", "B", "B", "B", NA, NA, "C", NA,
  3. NA, NA, "A", "A", "B", NA, NA)
  4. goodIdx <- !is.na(x)
  5. goodIdx
  6. #> [1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE FALSE
  7. #> [9] FALSE TRUE FALSE FALSE FALSE TRUE TRUE TRUE
  8. #> [17] FALSE FALSE
  9. # 这些是来自x的非NA数值
  10. # 加入领头的NA,后边会使用。用来进行索引
  11. goodVals <- c(NA, x[goodIdx])
  12. goodVals
  13. #> [1] NA "A" "A" "B" "B" "B" "C" "A" "A" "B"
  14. # 用来自输出向量的索引填充输出向量的索引
  15. # 这些补偿了goodVals。加1是为了避免索引为0
  16. fillIdx <- cumsum(goodIdx) + 1
  17. fillIdx
  18. #> [1] 1 1 2 3 4 5 6 6 6 7 7 7 7 8 9 10 10
  19. #> [18] 10
  20. # 原本向量的值被填充了

6.23.2.1 填充 NA 的函数

此函数执行与上面代码相同的操作。它还可以用第一个良好的值填充第一个就是NA的情况,并正确处理因子。

  1. fillNAgaps <- function(x, firstBack = FALSE) {
  2. ## 向量或因子中的 NA 被之前一个非 NA 值代替 如果
  3. ## firstBack 为 TRUE,将会对领头的 NA 填充第一个非 NA
  4. ## 值,否则不会
  5. ## 如果是一个因子,保存因子的水平,并转换为整数
  6. lvls <- NULL
  7. if (is.factor(x)) {
  8. lvls <- levels(x)
  9. x <- as.integer(x)
  10. }
  11. goodIdx <- !is.na(x)
  12. # 这些是来自于x的非NA值
  13. # 加入领头NA或者以第一个值代替,取决于firstBack参数
  14. if (firstBack)
  15. goodVals <- c(x[goodIdx][1], x[goodIdx]) else goodVals <- c(NA, x[goodIdx])
  16. # 用来自输出向量的索引填充输出向量的索引
  17. # 这些补偿了goodVals。加1是为了避免索引为0
  18. fillIdx <- cumsum(goodIdx) + 1
  19. x <- goodVals[fillIdx]
  20. # 如果它最初是一个因子,那么将它转换回来
  21. if (!is.null(lvls)) {
  22. x <- factor(x, levels = seq_along(lvls), labels = lvls)
  23. }
  24. x
  25. }
  26. # 示例数据
  27. x <- c(NA, NA, "A", "A", "B", "B", "B", NA, NA, "C", NA,
  28. NA, NA, "A", "A", "B", NA, NA)
  29. x
  30. #> [1] NA NA "A" "A" "B" "B" "B" NA NA "C" NA NA
  31. #> [13] NA "A" "A" "B" NA NA
  32. fillNAgaps(x)
  33. #> [1] NA NA "A" "A" "B" "B" "B" "B" "B" "C" "C" "C"
  34. #> [13] "C" "A" "A" "B" "B" "B"
  35. # 对领头的 NA 以第一个非 NA 值进行填充
  36. fillNAgaps(x, firstBack = TRUE)
  37. #> [1] "A" "A" "A" "A" "B" "B" "B" "B" "B" "C" "C" "C"
  38. #> [13] "C" "A" "A" "B" "B" "B"
  39. # 因子数据也能使用
  40. y <- factor(x)
  41. y
  42. #> [1] <NA> <NA> A A B B B <NA> <NA> C
  43. #> [11] <NA> <NA> <NA> A A B <NA> <NA>
  44. #> Levels: A B C
  45. fillNAgaps(y)
  46. #> [1] <NA> <NA> A A B B B B B C
  47. #> [11] C C C A A B B B
  48. #> Levels: A B C

6.23.2.2 注释

改编自来自于 zoo 包的 na.locf() 函数。