knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)

ggplot2::theme_set(ggplot2::theme_minimal())

angularsweep

R build status

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.

Installation

You can install the released version of angularsweep from GitHub with the following command:

remotes::install_github("https://github.com/gtm19/angularsweep")

Points Example

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)

Weighted Example

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)


gtm19/angularsweep documentation built on July 27, 2020, 2 p.m.