用从邻居计算的值替换R数值向量中的NA

时间:2014-11-05 10:23:46

标签: r

我正在尝试编写一个replacena()函数,它将给定数值向量中的每个缺失值替换为其前后元素算术平均值。例如,如果给出(5,NA,6,2,3,5,6,4,NA,2,NA,5),那么结果应该是(5,5.5,6,2,3,5, 6,4,3,2,3.5,5)。

我正在寻找一些优雅的解决方案,可能还有应用功能(没有控制流程结构),但我还没有找到任何有效的方法。我不太确定如何访问lambda函数(x)中的上一个和下一个元素。

replacena <- function(l)
{
   stopifnot(is.numeric(l))
   sapply(l[is.na(l)], function(x){ l[x] <- mean( c(l[-1:0], l[0:1]) ) } )
}

所以说明:

replacena(c(5, NA, 6, 2, 3, 5, 6, 4, NA, 2, NA, 5))

应该产生输出:

(5, 5.5, 6, 2, 3, 5, 6, 4, 3, 2, 3.5, 5)

初学者的想法?谢谢。

3 个答案:

答案 0 :(得分:4)

尝试

library(zoo)
na.approx(v1)
[1] 5.0 5.5 6.0 2.0 3.0 5.0 6.0 4.0 3.0 2.0 3.5 5.0

数据

v1 <- c(5, NA, 6, 2, 3, 5, 6, 4, NA, 2, NA, 5)

答案 1 :(得分:2)

如果我们重新发明轮子(请参阅akruns答案),我们可以通过将您的功能修改为以下内容来实现此目的:

replacena <- function(l) {
  stopifnot(is.numeric(l))
  indx <- is.na(l)
  l[indx] <- vapply(which(indx), function(x) mean(c(l[x - 1], l[x + 1])), FUN.VALUE = double(1))
  l
}


replacena(c(5, NA, 6, 2, 3, 5, 6, 4, NA, 2, NA, 5))
## [1] 5.0 5.5 6.0 2.0 3.0 5.0 6.0 4.0 3.0 2.0 3.5 5.0

或者你的函数的矢量化版本(不使用*apply循环)

replacena2 <- function(l) {
  stopifnot(is.numeric(l))
  indx <- which(is.na(l))
  l[is.na(l)] <- rowMeans(cbind(l[indx - 1], l[indx + 1]))
  l
}

replacena2(c(5, NA, 6, 2, 3, 5, 6, 4, NA, 2, NA, 5))
## [1] 5.0 5.5 6.0 2.0 3.0 5.0 6.0 4.0 3.0 2.0 3.5 5.0

答案 2 :(得分:0)

尝试:

for(i in 1:length(xx)) if(is.na(xx[i]))
         xx[i] = ifelse(is.na(xx[i+1]),     xx[i-1],    (xx[i-1]+xx[i+1])/2)

xx
 [1] 5.0 5.5 6.0 2.0 3.0 5.0 6.0 4.0 3.0 2.0 3.5 5.0