在r

我有一个在边界处包含NA的向量

x <- c(NA,-1,1,NA,2,NA)

我希望结果是:

c(-3,5,8)

换句话说,我想用线性插值法填充内部和边界NA(也许我不能称其为“ inter -polation”,因为NA位于边界)。

我尝试了“ zoo”包中的一个函数na.fill(x,“ extend”),但是边界输出不是我想要的东西,它只重复最左边或最右边的非NA值:

na.fill(x,"extend")

输出为

[1] -1 -1  1 -1  1  0 -1  2  2  2

我还检查了用于填充NA的其他函数,例如na.approx(),na.locf()等,但是它们都不起作用。

na.spline确实有效,但是边界NA的输出导致极大的变化。

na.spline(x)

输出为:

 [1] -15.9475983  -1.0000000   1.0000000  -1.0000000   1.0000000   0.3400655  -1.0000000   2.0000000
 [9]  13.1441048  35.9323144

边界点太大。谁能帮我吗?预先感谢!

momate 回答:在r

您可以使用na.spline()库中的zoo

na.spline(x)

[1] 0.0 0.5 1.0 1.5 2.0 2.5

原始问题的数据:

x <- c(0,NA,1,2,NA)
,

鉴于问题编辑后的数据和预期输出,我相信以下功能可以实现。它用NA填充内部approxfun,然后一个个对待极端。

na.extrapol <- function(y){
  x <- seq_along(y)
  f <- approxfun(x[!is.na(y)],y[!is.na(y)])
  y[is.na(y)] <- f(x[is.na(y)])
  r <- rle(is.na(y))
  if(r$values[1]){
    Y <- y[r$lengths[1] + 1:2]
    X <- seq_len(r$lengths[1])
    y[rev(X)] <- Y[1] - diff(Y)*X
  }
  n <- length(r$lengths)
  if(r$values[n]){
    s <- sum(r$lengths[-n])
    Y <- y[s - 1:0]
    X <- seq_len(r$lengths[n])
    y[s + X] <- Y[2] + diff(Y)*X
  }
  y
}

x <- c(NA,-1,NA)
na.extrapol(x)
#[1] -3 -1  1 -1  1  0 -1  2  5  8

x2 <- c(NA,NA)
na.extrapol(x2)
#[1] -5 -3 -1  1 -1  1  0 -1  2  5  8
,

这是一种实现方法:

首先,我们进行线性逼近,这将使我们从左到右拥有所有 tail NA-s:

x <- na.approx(x,method = "constant",f = 0.5,na.rm = F)

现在让我们找到非NA向量以及相关的最左和最右算术级数增量项:

x_c <- x[!is.na(x)]
left <- x_c[1] - x_c[2]
right <- x_c[length(x_c)] - x_c[length(x_c) - 1]

现在是时候用算术级数获得的数字向左右NA-s填充:

ind_x<- which(!is.na(x))
big_M <- 100

x[(ind_x[length(ind_x)]):length(x)] <- seq(x[ind_x[length(ind_x)]],sign(right) * big_M,right)[1:(length(x) - ind_x[length(ind_x)] + 1)]
x[ind_x[1]:1] <- seq(x[ind_x[1]],sign(left) * big_M,left)[1:ind_x[1]]
y <- x

其中big_M是用户定义的大数,给定基础数据,则算术级数不会超过该数字。

输入-输出:

x <- c(NA,NA)
> y
 [1] -3 -1  1 -1  1  0 -1  2  5  8

x <- c(NA,NA)
> y
 [1] -7 -5 -3 -1  1 -1  1  0 -1  2  5  8 11

x <- c(NA,5,NA)
> y
 [1] 17 13  9  5  1  1 -1  1  0 -1  2  5  8 11
,

除了考虑Hmisc::approxExtrap之外,另一种选择是使用lm,但它很可能会比这里的其他选项慢

x <- c(NA,NA)
DF <- data.frame(i=seq_along(x),x)
cc <- DF[complete.cases(DF),]
DF$x <- approx(cc$i,cc$x,DF$i)$y
hh <- head(cc,2L)
tt <- tail(cc,2L)
DF$x[DF$i < hh$i[1L]] <- predict(lm(x ~ i,hh),DF[DF$i < hh$i[1L],"i",drop=FALSE])
DF$x[DF$i > tt$i[2L]] <- predict(lm(x ~ i,tt),DF[DF$i > tt$i[2L],drop=FALSE])
DF

输出:

    i  x
1   1 -3
2   2 -1
3   3  1
4   4 -1
5   5  1
6   6  0
7   7 -1
8   8  2
9   9  5
10 10  8
本文链接:https://www.f2er.com/3128514.html

大家都在问