Home > Software engineering >  How to exclude points beyond a line in R
How to exclude points beyond a line in R

Time:05-25

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.

enter image description here

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)

enter image description here

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)

enter image description here

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")

enter image description here

  • Related