knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" ) ggplot2::theme_set(ggplot2::theme_minimal())
angularsweep
contains functions which implement the angular sweep algorithm in order
to determine the circle with specified radius which contains the maximum number of a provided set of
points in two dimensional space.
The sweep_points()
function will apply the algorithm to a data frame of points in two dimensions. The sweep_latlons
function will attempt to re-project coordinates to do the same for geographic locations.
It can also apply the same algorithm with a weighting variable: giving the circle with the weighted maximum number of points within it. This could be used, for example, to identify the circle containing the largest aggregate value of a number of buildings, given their values.
You can install the released version of angularsweep from GitHub with the following command:
remotes::install_github("https://github.com/gtm19/angularsweep")
First constructing an arbitrary data frame of points clustered around two points:
library(ggplot2) library(ggforce) library(angularsweep) set.seed(1) points <- data.frame( x = c( rnorm(25, 0), rnorm(25, 5) ), y = c( rnorm(25, 0), rnorm(25, 5) ), group = c( rep(1, 25), rep(2, 25) ) ) point_plot <- ggplot(points, aes(x, y)) + geom_point() + coord_equal() + labs(colour = "Points in circle") + scale_color_brewer(palette = "GnBu")
It seems clear that ascertaining the circles with radius 2.5
with the largest number of points within is going to yield at most two circles with 25 points in each:
r <- 2.5 point_sweep <- sweep_points(points, xcol = "x", ycol = "y", radius = r) point_plot + geom_circle(data = point_sweep[1:2,], aes(x0 = x, y0 = y, r = r, colour = factor(total)), inherit.aes = FALSE, size = 1.2)
However, increasing the radius to traverse the two clusters can result in a circle with more than 25 points within.
r <- 3.5 point_sweep <- sweep_points(points, xcol = "x", ycol = "y", radius = r) point_plot + geom_circle(data = point_sweep[1:5,], aes(x0 = x, y0 = y, r = r, colour = factor(total)), inherit.aes = FALSE, size = 1.2)
Likewise, picking a smaller radius will help locate local clusters of points:
r <- 0.75 point_sweep <- sweep_points(points, xcol = "x", ycol = "y", radius = r) point_plot + geom_circle(data = point_sweep[1:5,], aes(x0 = x, y0 = y, r = r, colour = factor(total)), inherit.aes = FALSE, size = 1.2)
What if you wanted to know the biggest value within a circle of a given radius, where the value of each point is determined by a weighting variable? No problem.
Below, we first create a data frame of 28 points, 25 of which are clustered around (0, 0)
, with a low value, and 3 of which are clustered around (5, 5)
with a high value:
set.seed(1) points <- data.frame( x = c( rnorm(25, 0), rnorm(3, 5) ), y = c( rnorm(25, 0), rnorm(3, 5) ), w = c( rep(10, 25), rep(1000, 3) ) )
Sweeping the points with circles of radius 2.5
identifies the cluster of 3 points as having the highest value in any single circle:
r <- 2.5 point_sweep <- sweep_points(points, xcol = "x", ycol = "y", weight = "w", radius = r) ggplot(points, aes(x, y)) + geom_point() + coord_equal() + labs(colour = "Value in circle") + scale_color_brewer(palette = "GnBu") + geom_circle(data = point_sweep[1,], aes(x0 = x, y0 = y, r = r, colour = factor(total)), inherit.aes = FALSE, size = 1.2)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.