简体   繁体   English

R:填充R中的空位的双线性插值

[英]R: Bilinear interpolation to fill gaps in R

I have a grid that contains gaps (NAs) that I want to fill using interpolation. 我有一个网格,其中包含我想用插值填充的间隙(NA)。 My grid shows autocorrelation in the x and y dimensions, so I would like to try bilinear interpolation. 我的网格显示x和y维度的自相关,所以我想尝试双线性插值。 Most of the solutions I have found are focused on 'upsampling' (interpolation for the purpose of increasing number of samples/size of grid), but I do not want/need to change the grid size. 我发现的大多数解决方案都集中在“上采样”(插值以增加采样数/网格大小),但我不想/需要更改网格大小。 I just want to fill NAs using interpolation. 我只是想用插值填充NA。 Other potential solutions do not seem to handle NAs for the input grid of values (the 'z matrix') , or are neighborhood-based solutions rather than bilinear interpoloation, or simply have no answer . 其他潜在的解决方案似乎并不处理输入网格值(“z矩阵”)的NA ,或者是基于邻域的解决方案而不是双线性插值,或者根本没有答案

I found that with the raster package, I can input a grid (as a raster) that contains NAs, and use the 'resample' command to output a grid of the same size. 我发现使用光栅包,我可以输入包含NA的网格(作为栅格),并使用'resample'命令输出相同大小的网格。 However, the results look like nearest neighbor interpolation rather than bilinear interpolation. 但是,结果看起来像最近邻插值而不是双线性插值。

Am I missing something such that there is a way to do bilinear interpolation with the raster package? 我错过了一些方法,可以用光栅包进行双线性插值吗? Or is there a better way to do bilinear interpolation simply to fill NAs? 或者是否有更好的方法来完成双线性插值以填充NA?

library(raster)

# raster containing gap
r <- raster(nrow=10, ncol=10)
r[] <- 1:ncell(r)
r[25] <- NA

# The s raster is the same size as the r raster
s <- raster(nrow=10, ncol=10)
s <- resample(r, s, method='bilinear')
plot(r)
plot(s)
s[25]
s[35]
# s[25] appears to have been filled with neighbor s[35]

UPDATE UPDATE

The Akima package seems like a promising alternative to the raster approach above, but I'm having trouble if there are NAs in the input grid of values (the Z matrix). Akima包似乎是上面栅格方法的一个有前途的替代方案,但是如果在输入网格值(Z矩阵)中存在NA,我会遇到麻烦。 Here's an example parallel to the example above to demonstrate. 这是一个与上面的例子平行的例子来演示。 (Again, I'm interpolating to a grid the same size as the original). (同样,我正在插入与原始网格大小相同的网格)。

library(akima)

# Use bilinear interpolation (no NAs in input)
rmat<-matrix(seq(1,100,1), nrow = 10, ncol = 10, byrow = T)
x <- seq(1,10,1)
y <- seq(1,10,1)
smat <- bilinear.grid(x, y, rmat, nx = 10, ny = 10) # works
plot(raster(rmat), main = "original")
plot(raster(smat$z), main = "interpolated")

# Try using bilinear interpolation but with an NA
rmat<-matrix(seq(1,100,1), nrow = 10, ncol = 10, byrow = T)
rmat[3,5] <- NA
x <- seq(1,10,1)
y <- seq(1,10,1)
smat <- bilinear.grid(x, y, rmat, nx = 10, ny = 10) # Error about NAs

UPDATE2 UPDATE2

There was a great question from @Robert Hijmans about why not use a moving window average with the focal() command in the raster package. @Robert Hijmans提出了一个很好的问题,即为什么不在光栅包中使用focal()命令来移动平均窗口。 The reason is that I want to try bilinear interpolation, and I don't think a moving window average always gives the same answer as bilinear interpolation. 原因是我想尝试双线性插值,我不认为移动窗口平均值总是给出与双线性插值相同的答案。 However, this was not clear in the example I posted (in that example moving window and bilinear interp do give the same answer), so I'll demonstrate in a new example below. 但是,在我发布的示例中并不清楚(在该示例中,移动窗口和双线性interp 确实给出了相同的答案),因此我将在下面的新示例中进行演示。 Note that the bilinear interpolation solution should be 8 for the example below ( here is a handy calculator for tests ). 请注意,下面的示例中的双线性插值解决方案应为8( 这是一个方便的测试计算器 )。

library(raster)
r <- raster(nrow=10, ncol=10)

# Different grid values than earlier examples
values(r) <- c(rep(1:5, 4), rep(4:8, 4), rep(1:5, 4), rep(4:8, 4), rep(1:5, 4))
r[25] <- NA
plot(r)

# See what the mean of the moving window produces
f <- focal(r, w=matrix(1,nrow=3, ncol=3), fun=mean, NAonly=TRUE, na.rm=TRUE) 
f[25] # Moving window gives 5 but bilinear interp gives 8

# Note that this seems to be how the moving window works with equal weights
window_test <- c(r[14:16], r[24:26], r[34:36])
 mean(window_test, na.rm = T)

Am I missing something here? 我在这里错过了什么吗? Maybe there is something clever with the weights argument of focal() that can produce a bilinear interpolation solution? 也许有一些聪明的,使用focal()的权重参数可以产生双线性插值解?

Let's use equal distance cells to avoid differences because of cell size variation with lon/lat data 让我们使用等距离单元来避免差异,因为lon / lat数据的单元大小变化

library(raster)
r <- raster(nrow=10, ncol=10, crs='+proj=utm +zone=1 +datum=WGS84', xmn=0, xmx=1, ymn=0, ymx=1)

For this example, you might use focal 对于此示例,您可以使用focal

values(r) <- 1:ncell(r)
r[25] <- NA
f <- focal(r, w=matrix(1,nrow=3, ncol=3), fun=mean, NAonly=TRUE, na.rm=TRUE) 

I see that you dismiss "neighborhood-based solutions rather than bilinear interpoloation". 我看到你忽略了“基于邻域的解决方案,而不是双线性插入”。 But the question is why. 但问题是为什么。 In this case, you may want a neighborhood-based solution. 在这种情况下,您可能需要基于邻域的解决方案。

Update. 更新。 Then again, in case of cells that are not approximately square, bilinear would be preferable. 然后,在细胞不是近似正方形的情况下,双线性将是优选的。

values(r) <- c(rep(1:5, 4), rep(4:8, 4), rep(1:5, 4), rep(4:8, 4), rep(1:5, 4))
r[25] <- NA

The problem with bilinear interpolation normally uses 4 contiguous cells, but in this case, where you want the value for the center of a cell, the appropriate cell would be the value of the cell itself, because the distance to that cell is zero, and thus that is where the interpolation ends up. 双线性插值的问题通常使用4个连续的单元格,但在这种情况下,您需要单元格中心的值,适当的单元格将是单元格本身的值,因为到该单元格的距离为零,并且因此,这就是插值结束的地方。 For example, for cell 23 例如,对于单元格23

extract(r, xyFromCell(r, 23))
#6
extract(r, xyFromCell(r, 23), method='bilinear')
#[1] 6

In this case the focal cell is NA, so you get the average of the focal cell and 3 more cells. 在这种情况下,焦点细胞是NA,因此您可以获得焦点细胞的平均值和另外3个细胞。 The question is which three? 问题是哪三个? It is arbitrary, but to make it work, the NA cell must get a value. 它是任意的,但要使其工作,NA单元必须得到一个值。 The raster algorithm assigns the value below the NA cell to that cell (also 8 here). raster算法将NA单元格下方的值分配给该单元格(此处也为8)。 This works well, I think, to deal with NA values at edges (eg land/ocean), but perhaps not in this case. 我认为,这很好地处理边缘(例如陆地/海洋)的NA值,但在这种情况下可能不是这样。 ` extract(r, xyFromCell(r, 25)) #NA extract(r, xyFromCell(r, 25), method='bilinear') #[1] 8 `extract(r,xyFromCell(r,25))#NA extract(r,xyFromCell(r,25),method ='bilinear')#[1] 8

That is also what resample gives 这也是resample

resample(r, r)[25]
# 8

Is this what the on-line calculator suggests too? 这也是在线计算器的建议吗?

This is very sensitive to small changes 这对小变化非常敏感

extract(r, xyFromCell(r, 25)+0.0001, method='bilinear')
#[1] 4.998997

What I would really want in this case is the mean of the rook-neighbors 在这种情况下我真正想要的是车友的意思

mean(r[adjacent(r, 25, pairs=FALSE)])
[1] 6

Or, more generally, the local inverse distance weighted average. 或者,更一般地,局部反距离加权平均值。 You can compute that by setting up a weights matrix with focal 您可以通过设置焦点矩阵来计算

# compute weights matrix
a <- sort(adjacent(r, 25, 8, pairs=F, include=TRUE))
axy <- xyFromCell(r, a)
d <- pointDistance(axy, xyFromCell(r, 25), lonlat=F)
w <- matrix(d, 3, 3)
w[2,2] <- 0
w <- w / sum(w)

# A simpler approach could be: 
# w <- matrix(c(0,.25,0,.25,0,.25,0,.25,0), 3, 3)


foc <- focal(r, w, na.rm=TRUE, NAonly=TRUE)
foc[25]

In this example this is fine; 在这个例子中,这很好; but it would not be correct if there were multiple NA values in the focal area (as the sum of weights would no longer be 1). 但如果焦点区域有多个NA值(因为权重之和不再是1),那就不正确了。 We can correct for that by computing the sum of weights 我们可以通过计算权重之和来纠正这个问题

x <- as.integer(r/r)
sum_weights <- focal(x, w, na.rm=TRUE, NAonly=TRUE)

fw <- foc/sum_weights
done <- cover(r, fw)
done[25]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM