3

I want to do a bilinear interpolation in R but I cant figure out how to do it with akima interp function because I get a matrix half fill with numbers and half with NA. This is an example of my problem:

x = rep(c(1,2,3,6,9,12)/12,5)
y = seq(2709,3820,length = 30)
z = seq(9.2,16.5,length = 30)

inter_lin = interp(x,y,z,xo = seq(min(x),max(x),length=100),
                   yo = seq(min(y), max(y), length=100), linear=T)

I also tried using the function interp.surface.grid form fields but z has to be a matrix with values for all x and y used which I don't have so it doesn't work.

EDIT This is the y and z vectors I actually have:

y = c(2931.076,2901.935,2868.635,2804.006,2760.297,2709.114,2983.466,2969.436,2954.808,2928.802,2915.815,2903.867,
      3043.365,3051.140,3057.960,3079.230,3103.015,3127.245,3118.090,3156.223,3194.574,3291.021,3380.687,3472.676,
      3195.631,3260.866,3331.776,3502.477,3658.052,3829.511)

z = c(10.280984,9.733925, 10.176117, 10.644877, 10.950297, 11.737252, 10.442495, 10.170472, 10.590579, 11.153778 ,11.501962,
  12.066833,11.000000, 11.025000, 11.450000, 12.125000, 12.550000, 12.875000, 12.142495, 11.870472, 12.390579, 13.053778,
  13.501962,14.066833,13.005984, 12.458925, 13.051117, 13.694877, 14.150297, 14.937252)
Ken Williams
  • 22,756
  • 10
  • 85
  • 147
Alejandro Andrade
  • 2,196
  • 21
  • 40

1 Answers1

2

Set linear = FALSE and extrap = TRUE.

x = rep(c(1,2,3,6,9,12)/12,5)
y = seq(2709,3820,length = 30)
z = seq(9.2,16.5,length = 30)

inter_lin = interp(x,y,z,xo = seq(min(x),max(x),length=100),
                   yo = seq(min(y), max(y), length=100), linear=FALSE, extrap = TRUE)

I think the problem is interpolating values on the boundary and this ripples inwards from the edges. By allowing extrapolation – which is not possible with linear interpolation – this issue is avoided.


Edit

If the interpolation domain is restricted to the region where there is data, results are just peachy.

library(akima)
library(spatialkernel)
library(fields)

# Create grid
grd <- expand.grid(x = seq(min(x),max(x),length=100), y = seq(min(y), max(y), length=100))

# Find points in convex hull
mask <- pinpoly(cbind(x, y)[chull(x, y),], as.matrix(grd))

# Crop grid to convex hull
grd <- grd[mask == 2,]

# Interpolate to points in convex hull
res <- interpp(x, y, z, xo = grd$x, yo = grd$y)

# Plot results
quilt.plot(res$x, res$y, res$z)

enter image description here

Dan
  • 11,370
  • 4
  • 43
  • 68
  • @Lyngbarj, I tried that but for some reason with my real data the interpolation is wrong. From column 22 to 23 it jumps from 10.07785 to 71.98672 and it keeps going wrong. I don't know why with this example it does work. I will update the question with the real data – Alejandro Andrade Nov 08 '17 at 16:43
  • @alejandroandrade I think this is because you're extrapolating *waaaay* outside your convex hull in the region where `x` is small and `y` is large and that errors from this region propagate throughout the upper part of the domain. My suggestion would be to define a custom grid bounded by your original convex hull and then use `interpp` to interpolate onto these points. – Dan Nov 08 '17 at 17:06
  • @Lyngbark I don't think that' s the problem because it if I divided the y vector by 1000 I keep getting the same error. I tried `interpp` but its i get NA anyway for some values. I thought this was more tribal, thanks anyway. – Alejandro Andrade Nov 08 '17 at 17:20
  • @alejandroandrade Why would dividing `y` by 1000 change anything? Plot y against x and look at the top left corner. There's a large area with no data. Now plot y/1000 against x. The large empty area is still there in the top left. You're trying to interpolate over an region with no data, hence the dodgy values. My advice: restrict your interpolation to the region where you *do* have data. – Dan Nov 08 '17 at 17:44
  • @alejandroandrade I've updated my answer to show exactly how to do it with a cropped interpolation domain. – Dan Nov 08 '17 at 18:06
  • @ Lyngbakr I understood wrong the convext hull. Any way that works, but i just have the question if it is possible to extrapolate outside the i don't have data – Alejandro Andrade Nov 08 '17 at 19:13
  • @alejandroandrade It is possible, but straying too far will produce weird results (like we saw before) as there are no data to guide the interpolation. You might be better off using some sort of statistical model instead. – Dan Nov 08 '17 at 19:46
  • I actually have an statistical model for the interpolation, but wanted to do it linear to compare it. – Alejandro Andrade Nov 08 '17 at 20:03