0

I am testing 2 different methods (m2b & hmm) for classifying the movement behaviour of penguins to ultimately classify feeding behaviour from GPS points and from these create kernel polygons to identify foraging areas. I want to check the overlap (area) between the foraging kernels from the 2 different methods. I have 1 SpatialPolygonsDataframe for each method which has a number of foraging kernels for each animal ID. Ultimately for each ID (which can be > 1 polygon) I want to calculate the overlap area between the 2 SpatialPolygonsDataframes. I have tried using rgeos::gIntersection:

o1 <- gIntersection(ud50_m2b,ud50_hmm,byid = T, id = 'ID')

but it returns the following error:

Error in RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, drop_lower_td, unaryUnion_if_byid_false,  :   ids vector has incorrect length of 1 expected length of 35910

My data looks like this:

> str(ud50_m2b)
Formal class 'SpatialPolygonsDataFrame' [package "sp"] with 5 slots
  ..

@ data       :'data.frame': 2 obs. of  4 variables:
  .. ..$ ID    : Factor w/ 2 levels "CB1201","CB1203": 1 2
  .. ..$ area  : num [1:2] 1971 1178
  .. ..$ survey: Factor w/ 15 levels "","April2012BI",..: 2 2
  .. ..$ n     : int [1:2] 3024 4326
  ..

@ polygons   :List of 2
  .. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
  .. .. .. ..@ Polygons :List of 3
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 435288 6250135
  .. .. .. .. .. .. ..@ area   : num 5857355
  .. .. .. .. .. .. ..@ hole   : logi FALSE
  .. .. .. .. .. .. ..@ ringDir: int 1
  .. .. .. .. .. .. ..@ coords : num [1:30, 1:2] 434056 433968 433882 433922 434056 ...
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 442476 6251628
  .. .. .. .. .. .. ..@ area   : num 13697898
  .. .. .. .. .. .. ..@ hole   : logi FALSE
  .. .. .. .. .. .. ..@ ringDir: int 1
  .. .. .. .. .. .. ..@ coords : num [1:64, 1:2] 439588 439576 439588 439740 439983 ...
  .. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
  .. .. .. .. .. .. ..@ labpt  : num [1:2] 442305 6247942
  .. .. .. .. .. .. ..@ area   : num 156406
  .. .. .. .. .. .. ..@ hole   : logi FALSE
  .. .. .. .. .. .. ..@ ringDir: int 1
  .. .. .. .. .. .. ..@ coords : num [1:8, 1:2] 442353 442112 442185 442353 442474 ...
  .. .. .. ..@ plotOrder: int [1:3] 2 1 3
  .. .. .. ..@ labpt    : num [1:2] 442476 6251628
  .. .. .. ..@ ID       : chr "CB1201"
  .. .. .. ..@ area     : num 19711659

I think there is an indexing issue here in that the gIntersection function does not register the same IDs for multiple polygons in each SpatialPolygonsDataframe. Is there a trick to getting the overall intersection area for each ID between the 2 SpatialPolygonsDataframe?

3
  • Have you tried it without specifying an id= argument? Does 35910 mean anything? Is it the number of rows in one of your data items? Can you make some sample data we can use into a reproducible example?
    – Spacedman
    Feb 21, 2019 at 17:41
  • Thanks Spacedman - I did manage to finally get this right with the following (long-winded) solution:
    – Al Mac
    Feb 22, 2019 at 5:49
  • I believe that the spatial.select in the spatialEco package will work for your problem. You will just have to play around with predicates. Sep 16, 2021 at 16:01

1 Answer 1

0
This is a bit long-winded but it works:

    library(rgeos)

overlap<-function(data1,data2){

o1 <- gIntersection(data1,data2,byid = T)

odf1 <- data.frame(id = getSpPPolygonsIDSlots(o1), intersect_area = gArea(o1, byid=TRUE))
odfmeth1 <- data.frame(id = getSpPPolygonsIDSlots(data1), aream1 = gArea(data1, byid=TRUE))
odfmeth2 <- data.frame(id = getSpPPolygonsIDSlots(data2), aream2 = gArea(data2, byid=TRUE))

odf <- odf1 %>% separate(id, into=c("id1","id2"), sep = ' ') %>%
  mutate(id = id1) %>%
  filter(id1==id2) %>%
  left_join(odfmeth1,by='id') %>%
  left_join(odfmeth2,by='id') %>%
  mutate(propm1 = intersect_area/aream1,
         propm2 = intersect_area/aream2) %>%
  dplyr::select(-id1,-id2)

}

ov_ud50_m2b_hmm<- overlap(ud50_m2b,ud50_hmm)
mean(ov_ud50_m2b_hmm$propm1)
sd(ov_ud50_m2b_hmm$propm1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.