I'm working with two dataframes in R: a "red" dataframe and a "black" dataframe. In both there are two columns representing the coordinates.
I used a plot to explain what I want to do.
I would like to select all the points from the "red" dataframe that are beyond the "black" line. E.g. all the points excluded from the area of the polygon delimited by the black points.
CodePudding user response:
You could use the sf
package to define a convex hull and intersect your target points with that polygon.
Define a convex hull based on black
:
library(sf)
set.seed(99)
red <- data.frame(x = runif(100,-10,10), y = runif(100,-4,4))
black <- data.frame(x = runif(100,-8,8), y = runif(100,-4,3))
# Convert df to point feature
blk <- st_as_sf(black, coords = c("x", "y"))
# Convert to multipoint
blk_mp <- st_combine(blk)
# Define convex hull
blk_poly <- st_convex_hull(blk_mp)
plot(black)
points(red, col = "red")
plot(blk_poly, add = TRUE)
Intersecting red
with the convex hull returns red
within that polygon:
rd <- st_as_sf(red, coords = c("x", "y"))
rd_inside <- st_intersection(rd, blk_poly)
plot(black)
points(red)
plot(blk_poly, add = TRUE)
plot(rd_inside, pch = 24, col = "red", bg = "red", add = TRUE)
CodePudding user response:
Seems that you can reconstruct the edges of the black polygon by simply joining every point to its nearest neighbor and its nearest neighbor in the opposite direction. Then perform point-in-polygon tests.
CodePudding user response:
One possible solution is to draw the polygon after the points and fill its outer area white. This cannot be done directly with polygon
or polypath
, because these functions can only fill the interiour of a polygon. You can however fill the area between two polygons with polypath
. Thus you can add a second polygon that encompasses (or goes beyond) the borders of your plot.
Here is an example that works in base R:
p.outer <- list(x=c(0,100,100,0), y=c(0,0,100,100))
p.inner <- list(x=c(20,40,80,50,40,30), y=c(30,20,70,80,50,60))
plot(p.outer, type="n")
points(runif(100, min=0, max=100), runif(100, min=0, max=100))
polypath(x=c(p.outer$x, NA, p.inner$x), y = c(p.outer$y, NA, p.inner$y), col ="white", rule="evenodd")