2

I am confused between over() and point.in.poly() functions returns.

Here is my sample code:

WA = readOGR(wd, "WA_MeshBlocks")
Midland = readOGR(wd, "MidlandShops")

head(WA@data)
     gid   mb_code16    mb_cat16  sa1_main16 sa1_7dig16 sa2_main16
1 315675 50000010000 Residential 50901123311    5123311  509011233
2 315676 50000020000 Residential 50901123307    5123307  509011233
3 315677 50000030000   Education 50901123311    5123311  509011233


head(Midland@data)
         id                  name        shop
1 606292009    Belvidere Supa IGA supermarket
2 702492538     Helena Valley IGA supermarket
3 748846100       The Pines Store convenience

print(proj4string(WA))
print(proj4string(Midland))
[1] "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"

dim(WA) #   [1] 42425    17
dim(Midland) #  [1] 46  3

Then, i used over() functions to know each location point in "Midland" object falls into which "WA" object. Since it returns a data frame that i-th geometry in WA corresponds to the i-th point location in Midland, cbind() is used to combine them.

spatial_overlay = over(Midland, WA, returnList=TRUE)
spatial_overlay = cbind(shop_name = Midland@data$name,
                        ID = sapply(spatial_overlay,rownames), 
                        do.call("rbind", spatial_overlay))
spatial_overlay
                         shop_name    ID    gid   mb_code16
1               Belvidere Supa IGA  2907 318581 50028940000
2                Helena Valley IGA 20218 335892 50223550000
3                  The Pines Store 19935 335609 50220290000
4                    IGA Swan View 20134 335808 50222780000
5            Farmer Jacks Stratton 36198 351872 50391495200
6                  Koongamia Store 28209 343883 50306010000
7                    Savage Suzuki 20144 335818 50222881000
8                          Polaris 20156 335830 50222930000
9               Midland Brickworks 28304 343978 50306913000
10 Middle Swan Liquor Store & Deli 28313 343987 50306990000
11               Houghton's Winery 28439 344113 50308311000
12                             BWS  3035 318709 50030160000
13        Middle Swan Liquor Store 28313 343987 50306990000
14                   Hair Dare You 20218 335892 50223550000
15            Liquor in the Valley 20218 335892 50223550000
16                        Supa IGA 28150 343824 50305510000
17               Bikeforce Midland 28237 343911 50306245000
18                  Midland Cycles 28241 343915 50306249000
19                 Skyway Bicycles 28240 343914 50306248000
20                  Gull Guildford 28132 343806 50305330000
21                   Thirsty Camel 28126 343800 50305240000
22           Better Pets n Gardens 28082 343756 50304793000
23                        7 Eleven 27474 343148 50299020000
24                      LiqourLand 20134 335808 50222780000
25                  Australian Way 40600 356274 50391938700
26                         Clarins 40600 356274 50391938700
27                  JR / Duty Free 40600 356274 50391938700
28                  JR / Duty Free 40600 356274 50391938700
29                  JR / Watch Co. 40600 356274 50391938700
30                             MAC 40600 356274 50391938700
31                        NewsLink 40600 356274 50391938700
32         Guildford Garden Centre 39510 355184 50391829700
33          The Honda Shop Midland 27468 343142 50298952000
34           Harvey Norman Midland 35952 351626 50391470100
35                      Woolworths 28233 343907 50306241000
36              BIG W Midland Gate 28233 343907 50306241000
37                          Target 28233 343907 50306241000
38                           Coles 28232 343906 50306230000
39                  JR / Duty Free 40600 356274 50391938700
40             The Cheesecake Shop 28223 343897 50306153000
41                        Mazparts 20150 335824 50222911000
42              Brumby's Swan View 20134 335808 50222780000
43             Mandoon Cellar Door 37319 352993 50391610600
44         Helena Estate Newsagent 20218 335892 50223550000
45                 Clayton Cellars 28209 343883 50306010000
46                         7eleven 28083 343757 50304800000

While point.in.poly() gives different order of shops names and "ID" and "name" order do not match together.

point.poly = point.in.poly(Midland, WA)
point.poly@data[,c(1,2,3,5)]
    ID   coords.x1 coords.x2                            name
1   2907  115.9404 -31.94642              Belvidere Supa IGA
2  20218  116.0202 -31.86820 Middle Swan Liquor Store & Deli
3  19935  115.9980 -31.85411               Houghton's Winery
4  20134  115.9396 -31.94282                             BWS
5  36198  116.0202 -31.86827        Middle Swan Liquor Store
6  28209  116.0288 -31.91577                   Hair Dare You
7  20144  116.0289 -31.91592            Liquor in the Valley
8  20156  116.0040 -31.89094                        Supa IGA
9  28304  116.0228 -31.89300               Bikeforce Midland
10 28313  116.0156 -31.89183                  Midland Cycles
11 28439  116.0190 -31.89232                 Skyway Bicycles
12  3035  116.0288 -31.91563               Helena Valley IGA
13 28313  115.9691 -31.90111                  Gull Guildford
14 20218  115.9715 -31.89968                   Thirsty Camel
15 20218  115.9567 -31.87534           Better Pets n Gardens
16 28150  116.0327 -31.88544                        7 Eleven
17 28237  116.0427 -31.88550                      LiqourLand
18 28241  115.9740 -31.94083                  Australian Way
19 28240  115.9738 -31.94078                         Clarins
20 28132  115.9739 -31.94089                  JR / Duty Free
21 28126  115.9738 -31.94091                  JR / Duty Free
22 28082  115.9739 -31.94074                  JR / Watch Co.
23 27474  116.0754 -31.91813                 The Pines Store
24 20134  115.9737 -31.94079                             MAC
25 40600  115.9745 -31.94073                        NewsLink
26 40600  115.9726 -31.89915         Guildford Garden Centre
27 40600  116.0099 -31.88647          The Honda Shop Midland
28 40600  116.0132 -31.89602           Harvey Norman Midland
29 40600  116.0083 -31.88926                      Woolworths
30 40600  116.0083 -31.88979              BIG W Midland Gate
31 40600  116.0097 -31.89024                          Target
32 39510  116.0116 -31.89010                           Coles
33 27468  115.9740 -31.94142                  JR / Duty Free
34 35952  116.0423 -31.88548                   IGA Swan View
35 28233  115.9977 -31.89000             The Cheesecake Shop
36 28233  116.0313 -31.89333                        Mazparts
37 28233  116.0425 -31.88549              Brumby's Swan View
38 28232  115.9946 -31.86810             Mandoon Cellar Door
39 40600  116.0290 -31.91554         Helena Estate Newsagent
40 28223  116.0399 -31.90687                 Clayton Cellars
41 20150  115.9746 -31.87553                         7eleven
42 20134  116.0350 -31.86924           Farmer Jacks Stratton
43 37319  116.0397 -31.90673                 Koongamia Store
44 20218  116.0288 -31.89408                   Savage Suzuki
45 28209  116.0346 -31.89525                         Polaris
46 28083  116.0079 -31.87172              Midland Brickworks

I get confused which functions give the correct results.

3
  • From what package are you getting point.in.poly()? There's a point.in.polygon() from sp but it takes numerical arrays, not sp objects.
    – Simbamangu
    Commented Feb 26, 2018 at 9:45
  • Thanks for your response. I used point.in.poly() from spatialEco package.
    – Marzieh
    Commented Mar 1, 2018 at 2:38
  • Could you share your data (or a subset of it)?
    – Simbamangu
    Commented Mar 5, 2018 at 6:24

1 Answer 1

1

Using cbind assumes all the rownames and IDs match up exactly as expected, and doesn't seem to be happening. You're re-creating an 'ID' column from an assumed order.

tl;dr - use a different order in over() and add data directly: Midland@data = cbind(Midland@data, over(Midland, WA))

Reproducible example:

# Create some spatial points and simple polygons
pts <- SpatialPointsDataFrame(
    coords = data.frame(x = rep(1:3, 3), 
    y = rep(1:3, each = 3)), data = data.frame(ptid = paste0('pt', 1:9)), 
    proj4string = CRS("+init=epsg:4326"))

Srs1 <- Polygons(list(Polygon(cbind(c(0.5, 1.5, 1.5, 0.5, 0.5), c(0.5, 0.5, 3.5, 3.5, 0.5)))), 3)
Srs2 <- Polygons(list(Polygon(cbind(c(1.5, 3.5, 3.5, 1.5, 1.5), c(0.5, 0.5, 3.5, 3.5, 0.5)))), 4)
spolys <- SpatialPolygonsDataFrame(SpatialPolygons(list(Srs1, Srs2), 1:2, proj4string = CRS("+init=epsg:4326")), data = data.frame(polname = c("A", "B"), row.names = row.names(polys)))

# Plot 'em
plot(spolys, border = 'red', lwd = 2); text(spolys, pos = 1, labels = spolys$polname, col= 'red')
points(pts, col = 'blue', pch = 19); text(pts, label = pts$ptid, pos = 3, cex = 0.6, col = 'blue')

Look at output from point.in.poly:

point.in.poly(pts, spolys)@data
#   pids ptid
# 1    3  pt1
# 2    4  pt2
# 3    4  pt3
# 4    3  pt4
# 5    4  pt5
# 6    4  pt6
# 7    3  pt7
# 8    4  pt8
# 9    4  pt9

Compare to your usage of over - produces the same results. Not sure why this isn't happening in your case?

spatial_overlay = over(pts, spolys, returnList=TRUE)
spatial_overlay = cbind(pt_name = pts$ptid,
                        ID = sapply(spatial_overlay, rownames), 
                        do.call("rbind", spatial_overlay))
spatial_overlay
#   pt_name ID polname
# 1     pt1  3       A
# 2     pt2  4       B
# 3     pt3  4       B
# 4     pt4  3       A
# 5     pt5  4       B
# 6     pt6  4       B
# 7     pt7  3       A
# 8     pt8  4       B
# 9     pt9  4       B

Much easier though, would be to reverse the parameters in over and bind the data directly:

s_o <- cbind(pts@data, over(pts, spolys))
s_o
#   ptid polname
# 1  pt1       A
# 2  pt2       B
# 3  pt3       B
# 4  pt4       A
# 5  pt5       B
# 6  pt6       B
# 7  pt7       A
# 8  pt8       B
# 9  pt9       B

Try adding the new columns directly to the point data by reversing the order of the over() parameters:

Midland@data = cbind(Midland@data, over(Midland, WA))

Not sure what is happening to your data, but now notice that you have a column ID (in capitals) in your point.in.poly output, but neither your original Midland or WA tables you show have an all-caps ID column. Where is that coming from?

4
  • Unfortunately, it is not possible to share the data files here but there are head of two spatial objects in my code.Thank you for helping me out but order of shops are still different.
    – Marzieh
    Commented Mar 9, 2018 at 2:41
  • @Marzieh, Please note that the point.in.poly function has been rewritten in the latest package version that just hit CRAN last week. Please update the package or install the development version on github. Commented Mar 10, 2018 at 14:44
  • Many thanks for giving me the answer. I can not directly use cbind(Midland@data, over(Midland, WA)) because over() returns a list while Midland@data is a data frame. The ID column is correspond to ID slot in WA polygons. These are ABS data.
    – Marzieh
    Commented Mar 20, 2018 at 8:40
  • over() should not return a list unless you specify returnList = TRUE, which is not what I suggested. Have you compared the example I made to your code steps? Also, why does ID not appear in your example after head(WA@data)?
    – Simbamangu
    Commented Mar 20, 2018 at 9:23

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.