R中向量的线性插值
Linear Interpolation over a vector in R
我有一个带有 NA
s 的数字向量,我想创建一个函数,根据 NA
s 之前和之后的数字对 NA 进行线性插值......有时函数需要生成一个数字,其他的不止一个
x <- c(1, NA, NA, 4, 5, 6, NA, 7, 8, NA, NA, NA, NA, 13, 14, 15)
第一步甚至是您用来在 1
和 4
之间线性插入前两个 NA
的步骤
approx(x = c(1,4), n = 2, method="linear")$x
- 一旦你有了一个函数,你就可以将它应用于整个向量,其中静态示例中的
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
背后的逻辑是:
- is.na(vec),转换成二进制链。
- 递归应用 bitmagic;从输出列表(并且对此很聪明),可以找到最长的 1 链的位置,这些位置对应于最长的 NA 链(所谓的块)。
- 确定块后,应用线性插值来填充 NA。
此外,请记住,如果向量的第一个或最后一个元素是 NA,此函数将失败(您不能在没有定义范围的情况下应用线性插值)。
如果您在学术环境中使用该功能,请注明。我很乐意回答您对代码的任何问题。最好的,
脑室。
我有一个带有 NA
s 的数字向量,我想创建一个函数,根据 NA
s 之前和之后的数字对 NA 进行线性插值......有时函数需要生成一个数字,其他的不止一个
x <- c(1, NA, NA, 4, 5, 6, NA, 7, 8, NA, NA, NA, NA, 13, 14, 15)
第一步甚至是您用来在 1
和 4
NA
的步骤
approx(x = c(1,4), n = 2, method="linear")$x
- 一旦你有了一个函数,你就可以将它应用于整个向量,其中静态示例中的
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
背后的逻辑是:
- is.na(vec),转换成二进制链。
- 递归应用 bitmagic;从输出列表(并且对此很聪明),可以找到最长的 1 链的位置,这些位置对应于最长的 NA 链(所谓的块)。
- 确定块后,应用线性插值来填充 NA。
此外,请记住,如果向量的第一个或最后一个元素是 NA,此函数将失败(您不能在没有定义范围的情况下应用线性插值)。
如果您在学术环境中使用该功能,请注明。我很乐意回答您对代码的任何问题。最好的,
脑室。