Reputation: 151
I have two spatial objects, one is points nc_point
(n=50) and the other is polygons sample_polygons
(n=20). Some of the points are fallen in polygons, which can be identified using the nc_point[sample_polygons , ]
function.
My question is how to obtain a subset of all the points that are NOT fallen in any polygons, i.e. the rest of the points?
# points layer contain 50 points
nc_point <- st_read(system.file("shape/nc.shp", package="sf")) %>%
st_centroid()
# the number of polygons is 20
set.seed(1)
sample_polygons <- st_read(system.file("shape/nc.shp", package="sf")) %>%
sample_n(20) %>%
select(geometry) # to mimic a situation where points are only identified using spatial correlation.
# points that fall in polygons can be identified using:
points_in <- nc_point[sample_polygons , ]
# how to find out points that are not fallen in any polygons?
Thanks, Phil
Upvotes: 4
Views: 2002
Reputation: 5932
Similar to Carlos answer but a tad simpler, leveraging function lengths
to get the length of each element of the intersects list:
outside <- nc_point[!lengths(st_intersects(nc_point, sample_polygons)), ]
# same as `outside <- nc_point[lengths(st_intersects(nc_point, sample_polygons)) == 0, ]`
outside
Simple feature collection with 80 features and 14 fields
geometry type: POINT
dimension: XY
bbox: xmin: -84.05976 ymin: 34.07663 xmax: -75.80982 ymax: 36.49101
epsg (SRID): 4267
proj4string: +proj=longlat +datum=NAD27 +no_defs
First 10 features:
AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79
1 0.114 1.442 1825 1825 Ashe 37009 37009 5 1091 1 10 1364 0 19
2 0.061 1.231 1827 1827 Alleghany 37005 37005 3 487 0 10 542 3 12
3 0.143 1.630 1828 1828 Surry 37171 37171 86 3188 5 208 3616 6 260
4 0.070 2.968 1831 1831 Currituck 37053 37053 27 508 1 123 830 2 145
5 0.153 2.206 1832 1832 Northampton 37131 37131 66 1421 9 1066 1606 3 1197
7 0.062 1.547 1834 1834 Camden 37029 37029 15 286 0 115 350 2 139
8 0.091 1.284 1835 1835 Gates 37073 37073 37 420 0 254 594 2 371
9 0.118 1.421 1836 1836 Warren 37185 37185 93 968 4 748 1190 2 844
10 0.124 1.428 1837 1837 Stokes 37169 37169 85 1612 1 160 2038 5 176
11 0.114 1.352 1838 1838 Caswell 37033 37033 17 1035 2 550 1253 2 597
geometry
1 POINT (-81.49826 36.4314)
2 POINT (-81.12515 36.49101)
3 POINT (-80.68575 36.41252)
4 POINT (-76.0275 36.40728)
5 POINT (-77.41056 36.42228)
7 POINT (-76.23435 36.4012)
8 POINT (-76.70448 36.44423)
9 POINT (-78.11043 36.39697)
10 POINT (-80.23428 36.40034)
11 POINT (-79.33477 36.39347)
Upvotes: 2
Reputation: 667
You could return an output with TRUE/FALSE to select your points. For example, look for length-0 elements in the list:
outside <- sapply(st_intersects(nc_point, sample_polygons),function(x){length(x)==0})
That gives you a logical vector you can subset with:
points_out <- nc_point[outside, ]
points_out
Simple feature collection with 80 features and 14 fields
geometry type: POINT
dimension: XY
bbox: xmin: -84.05976 ymin: 34.07663 xmax: -75.80982 ymax: 36.49101
epsg (SRID): 4267
proj4string: +proj=longlat +datum=NAD27 +no_defs
First 10 features:
AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79 geometry
1 0.114 1.442 1825 1825 Ashe 37009 37009 5 1091 1 10 1364 0 19 POINT (-81.49826 36.4314)
2 0.061 1.231 1827 1827 Alleghany 37005 37005 3 487 0 10 542 3 12 POINT (-81.12515 36.49101)
3 0.143 1.630 1828 1828 Surry 37171 37171 86 3188 5 208 3616 6 260 POINT (-80.68575 36.41252)
4 0.070 2.968 1831 1831 Currituck 37053 37053 27 508 1 123 830 2 145 POINT (-76.0275 36.40728)
5 0.153 2.206 1832 1832 Northampton 37131 37131 66 1421 9 1066 1606 3 1197 POINT (-77.41056 36.42228)
7 0.062 1.547 1834 1834 Camden 37029 37029 15 286 0 115 350 2 139 POINT (-76.23435 36.4012)
8 0.091 1.284 1835 1835 Gates 37073 37073 37 420 0 254 594 2 371 POINT (-76.70448 36.44423)
9 0.118 1.421 1836 1836 Warren 37185 37185 93 968 4 748 1190 2 844 POINT (-78.11043 36.39697)
10 0.124 1.428 1837 1837 Stokes 37169 37169 85 1612 1 160 2038 5 176 POINT (-80.23428 36.40034)
11 0.114 1.352 1838 1838 Caswell 37033 37033 17 1035 2 550 1253 2 597 POINT (-79.33477 36.39347)
Upvotes: 3