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.
My previous answer only showed how not to draw the points outside the polygon. To actually identify the points outside the polygon, you can use the function pip2d
from the package ptinpoly
. It returns negative values for points outside the polygon.
Example:
library(ptinpoly)
poly.vertices <- data.frame(x=c(20,40,80,50,40,30), y=c(30,20,70,80,50,60))
p <- data.frame(x=runif(100, min=0, max=100), y=runif(100, min=0, max=100))
outside <- (pip2d(as.matrix(poly.vertices), as.matrix(p)) < 0)
plot(p$x, p$y, col=ifelse(outside, "red", "black"))
polygon(poly.vertices$x, poly.vertices$y, border="blue", col=NA)
The same should be achieved with the function PtInPoly
from the package DescTools
, which returns zero for points outside the polygon. The implementation of ptinpoly
, however, has the advantage of implmenting the particularly efficient algorithm described in
J. Liu, Y.Q. Chen, J.M. Maisog, G. Luta: "A new point containment test algorithm based on preprocessing and determining triangles." Computer-Aided Design, Volume 42, Issue 12, December 2010, Pages 1143-1150
Edit: Out of curiosity, I have compared the runtime of ptinpoly::pip2d
and DescTools::PtInPoly
with microbenchmark and N=50000
points, and pip2d
turned out to be considerably faster:
> microbenchmark(outside.pip2d(), outside.PtInPoly())
Unit: milliseconds
expr min lq mean median uq max
outside.pip2d() 3.375084 3.421631 4.459051 3.48939 4.251395 65.97793
outside.PtInPoly() 27.537927 27.666688 28.739288 27.97984 28.514595 90.11313
neval 100 100