1

I have been unable to find any information specific to local block kriging with a local variogram using the gstat package in R. There is freeware called VESPER from the Australian Center for Precision Agriculture that is able to do this, and from what I have read it should be possible in R, I could just use some help with putting together a for-loop to make the gstat functions work locally.

Using the meuse data set as an example, I have been able to calculate and fit a global variogram to a data set:

    library(gstat)
    data(meuse)
    coordinates(meuse) = ~x+y
    data(meuse.grid)
    gridded(meuse.grid) = ~x+y

    logzinc_vgm<- variogram(log(zinc)~1, meuse)
    logzinc_vgm_fit <- fit.variogram(logzinc_vgm, model=vgm("Sph", "Exp"))
    logzinc_vgm_fit

    plot(logzinc_vgm, logzinc_vgm_fit)

This gives a nice plot of the variogram for the whole data set with the fitted model. Then I can use this to perform block kriging over the entire data set:

    logzinc_blkkrig <- krige(log(zinc)~1, meuse, meuse.grid, model = logzinc_vgm_fit, block=c(100,100))
    spplot(logzinc_blkkrig["var1.pred"], main = "ordinary kriging predictions")
    spplot(logzinc_blkkrig["var1.var"],  main = "ordinary kriging variance")

This produces a plot of the interpolated data as well as a plot of the variance for each predicted point. So this would be perfect if I wanted these functions to work once for my entire data set...

But I have been unable to generate a for-loop to handle these functions on a local level.

My goals are: 1. For each point in my grid file (which I have tried as both a data frame and SpatialPointsDataFrame), I would like to subset from my data file points within the distance diagonally of the range given in the global variogram (easy to call this location (i.e. logzinc_vgm_fit[2,3])) 2. On this subset of data, I would like to calculate the variogram (as above) and fit a model to it (as above) 3. Based on this model, I would like to perform block kriging to get a predicted value and variance at that grid point 4. Build the above three steps into a for-loop to predict values at each grid point based on the local variogram around each grid point

note: as with the meuse data set built into the gstat package, the dimensions of my grid and data data frames are different

Thank you very much for chiming in if anyone is able to tackle this question. Happy to post the code I am working with so far if it would be useful.

  • Have you verified for spatial subsets of your data extent whether or not the local variogram is statistically significantly different from the global variogram? I ask because if it is not different at a reasonable alpha level, you could save some programming time by using local block kriging with the global variogram. For example, specifying a `maxdist` equal to the range of the global variogram. – Jared Smith Dec 29 '16 at 21:18
  • Thank you for your reply, Jared. I've written code for block kriging with a global variogram already. The intention is to feed this into a web platform for spatial data processing, so both options need to be coded. – vineyard_surveyor Feb 24 '17 at 10:41

1 Answers1

1

I made a for loop that I think accomplishes what you request. I do not think that block kriging is required for this because the loop predicts at each grid cell.

The rad parameter is the search radius, which can be set to other quantities, but currently references the global variogram range (with nugget effect). I think it would be best to search a little further for points because if you only search up to the global variogram range, a local variogram fit may not converge (i.e. no observed range).

The k parameter is for the minimum number of nearest neighbors within rad. This is important because some locations may have no points within rad, which would result in an error.

You should note that the way you specified model=vgm("Sph", "Exp") seems to take the first listed method. So, I used the Spherical model in the for loop, but you can change to what you want to use. Matern may be a good choice if you think the shape will change with location.

#Specify the search radius for the local variogram
rad = logzinc_vgm_fit[2,3]
#Specify minimum number of points for prediction
k = 25
#Index to indicate if any result has been stored yet
stored = 0
for (i in 1:nrow(meuse.grid)){
  #Calculate the Euclidian distance to all points from the currect grid cell
  dists = spDistsN1(pts = meuse, pt = meuse.grid[i,], longlat = FALSE)

  #Find indices of the points within rad of this grid point
  IndsInRad = which(dists < rad)

  if (length(IndsInRad) < k){
    print('Not enough nearest neighbors')
  }else{
    #Calculate the local variogram with these points
    locVario = variogram(log(zinc)~1, meuse[IndsInRad,])

    #Fit the local variogram
    locVarioFit = fit.variogram(logzinc_vgm, model=vgm("Sph"))

    #Use kriging to predict at grid cell i. Supress printed output.
    loc_krig <- krige(log(zinc)~1, meuse[IndsInRad,], meuse.grid[i,], model = locVarioFit, debug.level = 0)

    #Add result to database
    if (stored == 0){
      FinalResult = loc_krig
      stored = 1
    }else{
      FinalResult = rbind(FinalResult, loc_krig)
    }
  }
}
Jared Smith
  • 280
  • 3
  • 12
  • I'm glad that this worked for you. Please indicate this as the answer to your question. – Jared Smith Mar 01 '17 at 21:39
  • the mentioned software "VESPER" also returns a variance value (I suppose it is dependent on the distance between input point value and predicted kriged cell value) - Is there a way to add this to your solution? – Ezra Mar 23 '18 at 07:32
  • I'm not familiar with VESPER, and the question did not ask for a VESPER solution, so I think this would not be the appropriate place for one. You could post a question about VESPER that links to this question, though. – Jared Smith Mar 24 '18 at 13:19