cigarettes_after_text
cigarettes_after_text

Reputation: 61

How to Calculate the Number of Coordinate Points that Occur within X Radius of Other Coordinate Points?

I have two sets of coordinate data (lat and long). The first set denotes positions of restaurants within the city. The second set of coordinates represents parks in the city. For each restaurant, I want to calculate the number of parks that are within 160 meters.

I tried using the simple features (sf) package to perform this operation, per another post, but am not getting the output I want.

Sample data:

Restaurants:

45.59841    -122.3275           
45.59932    -122.3343           
45.59932    -122.3343           
45.59820    -122.3343           
45.59820    -122.3343           
45.59814    -122.3340           
45.59814    -122.3340           
45.60016    -122.3341           
45.60016    -122.3341           
45.60020    -122.3343   

Parks:

45.61221    -122.3426           
45.61065    -122.3402           
45.60868    -122.3384           
45.60624    -122.3361           
45.61082    -122.3388           
45.60983    -122.3379           
45.60910    -122.3372           
45.60829    -122.3365           
45.60653    -122.3349           
45.60503    -122.3335   

Using sf, I tried to perform the following operations:

Turn coordinates into geospatial data

library(tidyverse)
library(sf)

park_points <- st_as_sf(ride_coords, coords = c(x = "Latitude", y = "Longitude"), crs = 4326)
rest_points <- st_as_sf(can_coords, coords = c(x = "lat", "lon"), crs = 4326)

I then tried to create a 160m buffer around each restaurant, after which I was hoping to attempt to calculate the number of parks residing in each of the restaurant buffers.

buffer_160 <- park_points %>% st_transform(26910) %>% st_buffer(dist = 160) %>% st_transform(2926)

I then received the following error:

"Error in UseMethod("st_transform") : no applicable method for 'st_transform' applied to an object of class "data.frame"

Anyway, the goal is to create buffers around each restaurant, then count the number of parks within each buffer (I know there will be overlap, so I will have to figure out how to handle this too)

I'm very new with R spatial tools. Thanks for any help!

Upvotes: 1

Views: 251

Answers (1)

Waldi
Waldi

Reputation: 41220

You could use spatialrisk::points_in_circle and map over the restaurants with purrr.

Didn't find parks in a radius of 160 m, so extended radius to 1000 m :

Restaurants <- read.table(text="
lat         lon                          
 45.59841    -122.3275           
 45.59932    -122.3343           
 45.59932    -122.3343           
 45.59820    -122.3343           
 45.59820    -122.3343           
 45.59814    -122.3340           
 45.59814    -122.3340           
 45.60016    -122.3341           
 45.60016    -122.3341           
 45.60020    -122.3343",header = T)

Parks <- read.table(text = "
lat     lon                  
45.61221    -122.3426           
45.61065    -122.3402           
45.60868    -122.3384           
45.60624    -122.3361           
45.61082    -122.3388           
45.60983    -122.3379           
45.60910    -122.3372           
45.60829    -122.3365           
45.60653    -122.3349           
45.60503    -122.3335",header = T)



library(purrr)
library(spatialrisk)

Restaurants %>% pmap(~with(list(...),points_in_circle(Parks, lon_center = lon, lat_center = lat,radius = 1000)))
#> [[1]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   872.6082
#> 
#> [[2]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   638.6807
#> 4  45.60624 -122.3361   782.9830
#> 9  45.60653 -122.3349   803.9727
#> 
#> [[3]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   638.6807
#> 4  45.60624 -122.3361   782.9830
#> 9  45.60653 -122.3349   803.9727
#> 
#> [[4]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   762.8609
#> 4  45.60624 -122.3361   905.9215
#> 9  45.60653 -122.3349   928.4681
#> 
#> [[5]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   762.8609
#> 4  45.60624 -122.3361   905.9215
#> 9  45.60653 -122.3349   928.4681
#> 
#> [[6]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   767.9792
#> 4  45.60624 -122.3361   916.4012
#> 9  45.60653 -122.3349   936.5971
#> 
#> [[7]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   767.9792
#> 4  45.60624 -122.3361   916.4012
#> 9  45.60653 -122.3349   936.5971
#> 
#> [[8]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   544.1362
#> 4  45.60624 -122.3361   694.5149
#> 9  45.60653 -122.3349   711.8371
#> 8  45.60829 -122.3365   924.1272
#> 
#> [[9]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   544.1362
#> 4  45.60624 -122.3361   694.5149
#> 9  45.60653 -122.3349   711.8371
#> 8  45.60829 -122.3365   924.1272
#> 
#> [[10]]
#>         lat       lon distance_m
#> 10 45.60503 -122.3335   541.2711
#> 4  45.60624 -122.3361   686.8285
#> 9  45.60653 -122.3349   706.2001
#> 8  45.60829 -122.3365   916.7284
#> 3  45.60868 -122.3384   996.5307

Or to summarize, use concentration which directly gives the number of parks around each restaurant:

Parks$count <- 1
spatialrisk::concentration(Restaurants, Parks, value = count, radius = 1000)

        lat       lon amount concentration
1  45.59841 -122.3275      1             1
2  45.59932 -122.3343      1             3
3  45.59932 -122.3343      1             3
4  45.59820 -122.3343      1             3
5  45.59820 -122.3343      1             3
6  45.59814 -122.3340      1             3
7  45.59814 -122.3340      1             3
8  45.60016 -122.3341      1             4
9  45.60016 -122.3341      1             4
10 45.60020 -122.3343      1             5

Upvotes: 2

Related Questions