我正在尝试编写一个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)
初学者的想法?谢谢。
答案 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