Hi,
I have a tibble with a set of cartesian coordinates of objects. I need to find a local density around each object. The local density I define as a number of objects reside in the circle around the object of interest. Other words I need to find a number of objects in a red circle minus one (in this example radius = 30) and repeat this for each point on the plot.
Previously I used square instead of circle as approximation but not I need to be more precise. Is there any simple algorithm / function to solve this task?
library(tidyverse)
library(ggforce)
#Sample data
df <- structure(
list(
ObjectNumber = 1:83,
Center_X = c(75.3622047244095, 118.418244406196,
138.2156133829, 151.69918699187, 152.115894039735, 166.151933701657,
170.233890214797, 178.8127090301, 195.203438395415, 197.945378151261,
202.595307917889, 219.089330024814, 228.208888888889, 239.743083003953,
260.227941176471, 4.80110497237569, 4.70967741935484, 4, 10.8529411764706,
12.8484848484848, 14.5706214689266, 10.7, 21.48125, 29.7473684210526,
31.3709677419355, 33.0898876404494, 160.535836177474, 157.873015873016,
74.6802325581395, 100.332764505119, 124.740196078431, 84.4304932735426,
104.28013029316, 128.556451612903, 139.678571428571, 168.125423728814,
168.129370629371, 181.983552631579, 198.579326923077, 223.676975945017,
2.06849315068493, 10.3079584775087, 13.4020100502513, 84.1421800947867,
94.2321428571429, 128.511627906977, 139.585106382979, 167.854237288136,
167.249134948097, 181.57328990228, 198.026378896883, 223.456790123457,
120.709874448592, 155.283625730994, 161.153439153439, 162.259541984733,
184.914285714286, 191.828571428571, 191.511764705882, 189.782805429864,
193.07881773399, 205.176470588235, 204.009411764706, 210.983870967742,
216.93536121673, 219.901098901099, 231.946472019465, 227.904761904762,
234.648910411622, 232.892307692308, 234.834239130435, 235.601286173633,
240.765243902439, 257.485714285714, 259.947692307692, 261.067708333333,
270.232727272727, 273.879518072289, 277.845425867508, 279.330275229358,
285.195599022005, 292.333333333333, 299.894736842105),
Center_Y = c(3.89763779527559,
22.6006884681583, 61.3122676579926, 11.1517615176152, 85.3973509933775,
43.4861878453039, 70.5298329355609, 7.57859531772575, 77.8080229226361,
27.5546218487395, 11.5923753665689, 23.3002481389578, 289.448888888889,
268.95256916996, 286.632352941176, 203.745856353591, 234.264516129032,
292.7, 185.957219251337, 219.411255411255, 253.189265536723,
269.733333333333, 275.18125, 235.361403508772, 197.322580645161,
223.797752808989, 124.0204778157, 109.320105820106, 54.2093023255814,
27.5546075085324, 10.8480392156863, 243.443946188341, 256.074918566775,
49.7983870967742, 53.1224489795918, 38.3220338983051, 66.9020979020979,
12.3157894736842, 37.7235576923077, 5.7319587628866, 42.7397260273973,
60.3840830449827, 28.7989949748744, 244.530805687204, 258.416666666667,
51.4496124031008, 54.1808510638298, 39.664406779661, 68.3840830449827,
13.6644951140065, 39.0023980815348, 6.41358024691358, 273.777740074652,
154.669590643275, 239.55291005291, 274.834605597964, 287.663492063492,
179.651948051948, 220.174509803922, 262.85520361991, 199.689655172414,
151.244705882353, 241.642352941176, 187.610215053763, 215.041825095057,
258.777472527473, 299.951338199513, 121.095238095238, 170.680387409201,
199.157692307692, 144.823369565217, 262.929260450161, 112.268292682927,
236.848214285714, 286.452307692308, 196.216145833333, 265.141818181818,
172.371485943775, 146.596214511041, 128.651376146789, 213.745721271394,
293.911270983213, 240.784380305603)),
row.names = c(NA, -83L),
class = c("tbl_df", "tbl", "data.frame"))
# Sample object
test_obj <- 7
# Desired radius around object
radius <- 30
ggplot() +
geom_point(data = df,
aes(x = Center_X,
y = Center_Y)) +
geom_circle(data = df[test_obj,],
aes(x0 = Center_X,
y0 = Center_Y,
r = radius),
color = "red") +
annotate(geom = "rect",
xmin = df[[test_obj, "Center_X"]] - radius,
xmax = df[[test_obj, "Center_X"]] + radius,
ymin = df[[test_obj, "Center_Y"]] - radius,
ymax = df[[test_obj, "Center_Y"]] + radius,
alpha = 0,
color = "blue") +
theme_classic()
# To count number of neighbors in a square around object, I came up with the
# following approach
count_neighbors <- function(x, y, Center_X, Center_Y, radius) {
sum(Center_X >= x-radius & Center_X <= x+radius &
Center_Y >= y-radius & Center_Y <= y+radius) - 1
}
df %>% mutate(density = map2_dbl(Center_X,
Center_Y,
~count_neighbors(.x,
.y,
Center_X,
Center_Y,
radius)))
#> # A tibble: 83 x 4
#> ObjectNumber Center_X Center_Y density
#> <int> <dbl> <dbl> <dbl>
#> 1 1 75.4 3.90 1
#> 2 2 118. 22.6 4
#> 3 3 138. 61.3 10
#> 4 4 152. 11.2 5
#> 5 5 152. 85.4 5
#> 6 6 166. 43.5 9
#> 7 7 170. 70.5 5
#> 8 8 179. 7.58 5
#> 9 9 195. 77.8 3
#> 10 10 198. 27.6 10
#> # ... with 73 more rows