R中向量的线性插值

Linear Interpolation over a vector in R

我有一个带有 NAs 的数字向量,我想创建一个函数,根据 NAs 之前和之后的数字对 NA 进行线性插值......有时函数需要生成一个数字,其他的不止一个

x <- c(1, NA, NA, 4, 5, 6, NA, 7, 8, NA, NA, NA, NA, 13, 14, 15)

第一步甚至是您用来在 14

之间线性插入前两个 NA 的步骤
approx(x = c(1,4), n = 2, method="linear")$x
  1. 一旦你有了一个函数,你就可以将它应用于整个向量,其中静态示例中的 n 是要填充的 NA 的数量,而 a, b 是值在 NA 的两侧?
interpolate <- function(a, b, n) {
  approx(x = c(a, b), n = n, method="linear")$x
}

如果这甚至是正确的方法,我如何将它们放在一起并将其应用于整个向量?其他人会如何处理这个问题?感谢任何帮助!!!

请查收我写成以下四个函数的解法:

linear_int_NA <- function(vec)
{
  BM_list = Reduce(f = function(x, y) bitmagic(x), x = 0:(length(vec)-2), init = is.na(vec), accumulate = TRUE)
  names(BM_list) = 1:(length(BM_list))
  BM_proc = Filter(length, lapply(rev(BM_list), function(x) which(x)))
  blocks = readBM(BM_proc)
  replace_x_lint(vec, blocks)
}

bitmagic <- function(bin)
{
  bin[-length(bin)] & bin[-1]
}

readBM <- function(BM_proc)
{
  blocks = matrix(NA, nrow = 0, ncol = 2); i = 1
  while(i <= length(BM_proc))
  {
    if(length(BM_proc[[i]]) > 0)
    {
      row = c(BM_proc[[i]], BM_proc[[i]] + as.numeric(names(BM_proc)[i]) - 1)
      blocks = rbind(blocks, row)
      pos = sapply(BM_proc, function(x) !(x%in% (row[1]):row[2]))
      Names = names(BM_proc)
      BM_proc = lapply(1:length(BM_proc), function(x) BM_proc[[x]][pos[[x]]])
      names(BM_proc) = Names
      BM_proc = Filter(length, BM_proc)
    }
  }
  return(blocks)
}

replace_x_lint <- function(vec, blocks)
{
  
  l_int = lapply(1:nrow(blocks), function(x) approx(x = vec[c(blocks[x,1] - 1, blocks[x,2] + 1)], 
                                                    n = blocks[x,2] - blocks[x,1] + 3, method="linear")$y[-c(1, blocks[x,2] - blocks[x,1] + 3)])
  for(i in 1:nrow(blocks))
  {
    vec[blocks[i,1]:blocks[i,2]] <- l_int[[i]]
  }
  return(vec)
}

要查看它们的实际效果,例如:

vec <- c(1, NA, NA, 4, 5, 6, NA, 7, 8, NA, NA, NA, NA, 13, 14, 15)
vec                # 1    NA   NA   4    5    6    NA   7    8    NA  NA   NA   NA   13   14   15
linear_int_NA(vec) # 1.0  2.0  3.0  4.0  5.0  6.0  6.5  7.0  8.0  9.0 10.0 11.0 12.0 13.0 14.0 15.0

如下所示:

plot(1:length(vec), linear_int_NA(vec), col = as.factor(is.na(vec)), pch = 19)

Output visualization

背后的逻辑是:

  1. is.na(vec),转换成二进制链。
  2. 递归应用 bitmagic;从输出列表(并且对此很聪明),可以找到最长的 1 链的位置,这些位置对应于最长的 NA 链(所谓的块)。
  3. 确定块后,应用线性插值来填充 NA。

此外,请记住,如果向量的第一个或最后一个元素是 NA,此函数将失败(您不能在没有定义范围的情况下应用线性插值)。

如果您在学术环境中使用该功能,请注明。我很乐意回答您对代码的任何问题。最好的,

脑室。