填充NA和x27;s在r中向量的边界处

填充NA和x27;s在r中向量的边界处,r,na,zoo,linear-interpolation,R,Na,Zoo,Linear Interpolation,我有一个向量,在边界处包含NA x <- c(NA, -1, 1,-1, 1, NA, -1, 2, NA, NA) 换句话说,我想用线性插值填充内部和边界NA(也许我不能称之为“内极化”,因为NA位于边界) 我在包“zoo”,na.fill(x,“extend”)中尝试了一个函数,但边界输出不是我想要的,它只是重复最左边或最右边的非na值: na.fill(x,"extend") 输出是 [1] -1 -1 1 -1 1 0 -1 2 2 2 我还检查了用于填充NA的其

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

x <- c(NA, -1, 1,-1, 1, NA, -1, 2, NA, NA)
换句话说,我想用线性插值填充内部和边界NA(也许我不能称之为“内极化”,因为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的输出会导致极大的变化

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

边界点太大。有人能帮我吗?提前谢谢

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

na.spline(x)

[1] 0.0 0.5 1.0 1.5 2.0 2.5
原始问题的数据:

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

x给定问题编辑后的数据和预期输出,我相信下面的函数可以做到这一点。它用
approxfun
填充内部
NA
,然后逐个处理极端情况

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, 1,-1, 1, NA, -1, 2, NA, NA)
na.extrapol(x)
#[1] -3 -1  1 -1  1  0 -1  2  5  8

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

na.extropol这里有一种方法:

首先,我们进行线性近似,这将使我们从左侧和右侧得到所有尾部
NA
-s:

x <- na.approx(x, method = "constant", f = 0.5,na.rm = F)
其中,
big_M
是一个用户定义的大数字,在给定基础数据的情况下,算术级数不会超过该数字

输入-输出:

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

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

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

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

x <- c(NA, -1, 1,-1, 1, NA, -1, 2, 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], "i", drop=FALSE])
DF

对不起,我没有把问题说清楚。你能检查一下我问题的当前版本吗?谢谢现在这是一个完全不同的问题。似乎相关:我怀疑是否会有一个现有的答案能够满足您的期望。似乎您希望使用内部NA的非缺失值两侧的方法以及两个相邻非缺失值的差异来扩展末端的NA位置。这并不是一个真正的标准程序,所以我认为如果您想要一个目标响应,您需要更仔细地指定规则。。。如果我对要使用的规则的猜测是正确的,你是对的。我想要的是填充现有的内部和外部位置(即边界点)。1) 对于内部点,使用线性插值是合理的,可以在几个包中找到。2) 但是,对于外部点,我没有找到标准的解决方案,因此我建议使用类似于“线性插值”的方法,从最近的两个非NA数据点获取信息。这种方法显然不够合理……另请参见上面的链接:“我想根据前面/后面的两个观察结果,使用线性近似法来推断边界[…],并附上
zoo
作者的答案。
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
x <- c(NA, -1, 1,-1, 1, NA, -1, 2, NA, NA)
> y
 [1] -3 -1  1 -1  1  0 -1  2  5  8

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

x <- c(NA,NA,NA, 5,1, 1,-1, 1, NA, -1, 2, NA, NA,NA)
> y
 [1] 17 13  9  5  1  1 -1  1  0 -1  2  5  8 11
x <- c(NA, -1, 1,-1, 1, NA, -1, 2, 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], "i", 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