3

I understand that the existence of duplicate points (locations) when Kriging will result in a singular covariance matrix. The only way I've encountered people dealing with this is to keep the first of any duplicate point and removing the rest.

But it seems rather wasteful to me to arbitrarily throw away data like that. So I am trying to write an R script which will take any duplicate locations in my data and replace with a single location and the mean of the variables.

The data I'm working with can be downloaded here (https://www.dropbox.com/sh/xnwp3zz5abnilyo/AABRVJZ0kTmWk0T9Fcp4-bVSa?dl=0/).

And here's how I attempted this:

library(rgdal)
library(sp)
library(maptools)

 #load data 

hs1<- readOGR (".", "Hollicombe_S1_L1-5_A1.2")

#remove columns we're not interested in

hs1<- subset(hs1, select = -c(1:16, 23:24))

So I start with hs1 - a SPDF with 552 obs and 6 variables...

#check for duplicate location (present if lengths differ)
length(hs1@coords) 
[1] 1104  
length(unique(hs1@coords))
[1] 730

This confirms there are duplicates. So now my attempt:

hs1.d <- hs1[duplicated(hs1@coords),] # creates new SPDF with only duplicated locations
hs1.u <- hs1[!duplicated(hs1@coords),] # creates new SPDF with only unique locations

# coerce duplicated locations SPDF to an ordinary data frame 

hs1.md<- as.data.frame(hs1.d)  

# combine the X&Y into a single "location"
hs1.md <- within(hs1.md,  
  Location <- paste(coords.x1, coords.x2, sep = ",")) 

# aggregate duplicate locations and calculate a mean value for each

means_by_location<-  aggregate (cbind(BioArea,BioVolume,MeanBioHei,MaxBioheig,PerArIn, PerVolIn)~Location,  hs1.md, mean)

#split location back to X&Y

lat_long <- strsplit(means_by_location$Location, ",") 
means_by_location$coords.x1 <- sapply(lat_long, function(x) x[1]) #adds X data back
means_by_location$coords.x2 <- sapply(lat_long, function(x) x[2])#adds Y data back
means_by_location$coords.x1 <- as.numeric (means_by_location$coords.x1) #converts to numeric
means_by_location$coords.x2 <- as.numeric (means_by_location$coords.x2)#converts to numeric

# add spatial information back in to create SPDF

coordinates(means_by_location) = ~coords.x1+coords.x2 # adds the locations 
proj4string(means_by_location) = CRS(proj4string(hs1)) # sets the CRS

# hs1.md as SPDF containing single rows for previously duplicated locations 
# with mean values for each variable

hs1.md <- subset(means_by_location, select = -(1))  

#merge hs1.md and hs1.u to create new SPDF without duplicates

hs1 <- spRbind (hs1.u, hs1.md)

So hs1 is now a SPDF with 543 obs (i.e. 9 observations have been removed).

But there still remain duplicate locations and the number of unique locations remains the same :

length(hs1@coords) # total number of locations
[1] 1086

length(unique(hs1@coords)) #number of unique locations
[1] 730

Can anyone spot where I have gone wrong? Or does anyone else have a similar method for dealing with duplicates?

  • 1
    I encountered similar problems when dealing with duplicates, mainly because coordinates have a lot of decimal values and R can only deal correctly with the first 16 decimals I think. Further decimals are estimated and may change after some calculations. To deal with that, I prefer calculating the distance with spDists between all locations and define manually which ones are duplicates (with a small tolerance values, dist <= tol). Then you can define groups and calculate the average value. – Sébastien Rochette Oct 6 '17 at 7:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.