当第一个观察结果为 na 时,使用 na.locf 传递最后一个值并忽略第一行

Using na.locf to carry last value forward ignoring first rows when first observation is na

我想利用 na.locf 结转数据帧的非缺失值,其中 第一次观察可能为零

问题

dta <- data.frame(A = c(NA, NA, 1, 2, 4, 5, NA, NA, NA),
                  B = c(NA, 5, 4, 5, 8, 9, NA, NA, 100))
dta %>% mutate_all(.funs = funs(na.locf(.)))

Error in mutate_impl(.data, dots) : Column A must be length 9 (the number of rows) or one, not 7

想要的结果

Vectorize(require)(package = c("dplyr", "zoo"),
                   character.only = TRUE)

dta <- data.frame(A = c(0, NA, 1, 2, 4, 5, NA, NA, NA),
                  B = c(0, 5, 4, 5, 8, 9, NA, NA, 100))
dta %>% mutate_all(.funs = funs(na.locf(.)))

解决方法

潜在的解决方法可能涉及用零替换第一组 NAs 并向前携带零,以后可以替换,但我有兴趣将 NA 留在原处并探索是否有方便的方法使 na.locf 忽略函数未接收到非 NA 值以开始替换的情况。

(@docendodiscimus 的评论出现时正在写这个答案)

来自?na.locf

na.rm logical. Should leading NAs be removed?

因此使用 na.rm=FALSE,可选择将剩余的 NA 值(即前导值)替换为零:

dta <- data.frame(A = c(NA, NA, 1, 2, 4, 5, NA, NA, NA),
                  B = c(NA, 5, 4, 5, 8, 9, NA, NA, 100))
na_zero <- function(x) replace(x,is.na(x),0)
dta %>% mutate_all(.funs = funs(na.locf(.,na.rm=FALSE))) %>%
   mutate_all(.funs=funs(na_zero(.)))

使用 na.rm = FALSE 参数,注意它可以占用整个数据框——您不必单独将它应用于每一列。

na.locf(dta, na.rm = FALSE)

这给出:

   A   B
1 NA  NA
2 NA   5
3  1   4
4  2   5
5  4   8
6  5   9
7  5   9
8  5   9
9  5 100

还有is na.locf0:

dta %>% mutate_all(.funs = funs(na.locf0(.)))

请参阅帮助页面 ?na.locf,其中记录了 na.rm 参数以及 na.locf0 。请注意,na.locf0 目前确实必须按列单独应用,但始终会产生相同长度的输出。

也许作为一个额外的提示,如果您正在使用包 imputeTSlocf 函数,您可以在几个选项之间进行选择通过参数 na.remaining 处理尾随 NAs :

na.remaining 的选择:

  • 保持” - return 带有 NAs 的系列
  • "rm" - 删除剩余的 NA
  • "mean" - 用总体平均值替换剩余的 NA
  • "rev" - 从反方向执行 nocb / locf

因此可以通过以下方式达到所需的输出:

dta <- data.frame(A = c(NA, NA, 1, 2, 4, 5, NA, NA, NA),
              B = c(NA, 5, 4, 5, 8, 9, NA, NA, 100))

library(imputeTS)
na.locf(dta, na.remaining = "keep")

此处不需要mutate_all,因为na.locf会自动应用于所有列(使用zoo的na.locf时也是如此)