用最新的非 NA 值替换 NA

标签 r data.table zoo r-faq

data.frame(或data.table)中,我想用最接近的先前非NA值“向前填充”NA。一个使用向量(而不是 data.frame)的简单示例如下:

> y <- c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA)

我想要一个函数fill.NAs(),它允许我构造yy,这样:

> yy
[1] NA NA NA  2  2  2  2  3  3  3  4  4

我需要对许多(总共~1 Tb)小型data.frame(~30-50 Mb)重复此操作,其中一行的所有条目都是NA。解决这个问题的好方法是什么?

我制定的丑陋解决方案使用了这个函数:

last <- function (x){
    x[length(x)]
}    

fill.NAs <- function(isNA){
if (isNA[1] == 1) {
    isNA[1:max({which(isNA==0)[1]-1},1)] <- 0 # first is NAs 
                                              # can't be forward filled
}
isNA.neg <- isNA.pos <- isNA.diff <- diff(isNA)
isNA.pos[isNA.diff < 0] <- 0
isNA.neg[isNA.diff > 0] <- 0
which.isNA.neg <- which(as.logical(isNA.neg))
if (length(which.isNA.neg)==0) return(NULL) # generates warnings later, but works
which.isNA.pos <- which(as.logical(isNA.pos))
which.isNA <- which(as.logical(isNA))
if (length(which.isNA.neg)==length(which.isNA.pos)){
    replacement <- rep(which.isNA.pos[2:length(which.isNA.neg)], 
                                which.isNA.neg[2:max(length(which.isNA.neg)-1,2)] - 
                                which.isNA.pos[1:max(length(which.isNA.neg)-1,1)])      
    replacement <- c(replacement, rep(last(which.isNA.pos), last(which.isNA) - last(which.isNA.pos)))
} else {
    replacement <- rep(which.isNA.pos[1:length(which.isNA.neg)], which.isNA.neg - which.isNA.pos[1:length(which.isNA.neg)])     
    replacement <- c(replacement, rep(last(which.isNA.pos), last(which.isNA) - last(which.isNA.pos)))
}
replacement
}

函数fill.NAs的使用如下:

y <- c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA)
isNA <- as.numeric(is.na(y))
replacement <- fill.NAs(isNA)
if (length(replacement)){
which.isNA <- which(as.logical(isNA))
to.replace <- which.isNA[which(isNA==0)[1]:length(which.isNA)]
y[to.replace] <- y[replacement]
} 

输出

> y
[1] NA  2  2  2  2  3  3  3  4  4  4

...这似乎有效。但是,伙计,这很丑吗!有什么建议吗?

最佳答案

您可能想使用 zoo 中的 na.locf() 函数包将最后的观察结果向前推进以替换您的 NA 值。

以下是帮助页面中其使用示例的开头:

library(zoo)

az <- zoo(1:6)

bz <- zoo(c(2,NA,1,4,5,2))

na.locf(bz)
1 2 3 4 5 6 
2 2 1 4 5 2 

na.locf(bz, fromLast = TRUE)
1 2 3 4 5 6 
2 1 1 4 5 2 

cz <- zoo(c(NA,9,3,2,3,2))

na.locf(cz)
2 3 4 5 6 
9 3 2 3 2 

关于用最新的非 NA 值替换 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7735647/

相关文章:

r - 使用二分搜索按范围对 data.table 进行子集化

r - 无法安装动物园包 (R)

r - 如何在动物园对象的 xyplot 中仅反转一个 y 轴

r - dplyr:汇总data.frame以获得最高值和最低值

r - 仅根据邮政编码在 R 中绘制热图

r - 为 networkD3 应用程序实现工具提示

r - 使用 data.table 包通过引用进行条件二进制连接和更新

将数据框中的每一列回归到 R 中的向量上

R的data.table找不到函数 "."

r - 从 Zoo::yearmon 对象中提取月份和年份