JeremyGelb/spNetwork

closest_points not working

IrenaItova opened this issue · 8 comments

Thank you for developing this package, very much needed!

I have issue with closest_points for calculating the nearest neighbour between two SpatialPointDataFrames, it returns this message:

Error in closest_points(x, y) : could not find function "closest_points"

I tried upgrading R to the latest 4.0.5 version, but that didn't help. I also tried downloading the package directly from your repo with devtools::install_github("JeremyGelb/spNetwork") with no luck either. Do you think I am missing any dependent package?

R version 4.0.5 (2021-03-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19042)
Matrix products: default

locale:
[1] LC_COLLATE=English_Netherlands.1252  LC_CTYPE=English_Netherlands.1252    LC_MONETARY=English_Netherlands.1252
[4] LC_NUMERIC=C                         LC_TIME=English_Netherlands.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] spNetwork_0.1.1 forcats_0.5.0   stringr_1.4.0   dplyr_1.0.0     purrr_0.3.4     readr_1.3.1     tidyr_1.1.0    
 [8] tibble_3.1.1    ggplot2_3.3.3   tidyverse_1.3.0 stplanr_0.7.2   spdep_1.1-7     spData_0.3.8    sf_0.9-8       
[15] rgdal_1.5-16    geojson_0.3.4   geojsonio_0.9.2 sp_1.4-5       

loaded via a namespace (and not attached):
 [1] cubature_2.0.4.1   colorspace_2.0-1   deldir_0.2-10      ellipsis_0.3.2     class_7.3-18       rprojroot_1.3-2   
 [7] fs_1.5.0           httpcode_0.3.0     rstudioapi_0.13    proxy_0.4-25       remotes_2.3.0      fansi_0.4.2       
[13] lubridate_1.7.9    xml2_1.3.2         codetools_0.2-18   splines_4.0.5      cachem_1.0.4       pkgload_1.2.1     
[19] jsonlite_1.7.0     broom_0.7.0        dbplyr_1.4.4       rgeos_0.5-5        compiler_4.0.5     httr_1.4.2        
[25] backports_1.1.7    assertthat_0.2.1   Matrix_1.3-2       fastmap_1.1.0      lazyeval_0.2.2     cli_2.5.0         
[31] prettyunits_1.1.1  tools_4.0.5        igraph_1.2.6       coda_0.19-4        gtable_0.3.0       glue_1.4.2        
[37] gmodels_2.18.1     tinytex_0.24       V8_3.2.0           Rcpp_1.0.6         cellranger_1.1.0   raster_3.4-10     
[43] vctrs_0.3.8        crul_1.0.0         gdata_2.18.0       nlme_3.1-152       xfun_0.15          ps_1.6.0          
[49] testthat_3.0.2     rvest_0.3.5        lifecycle_1.0.0    gtools_3.8.2       devtools_2.4.1     jqr_1.1.0         
[55] LearnBayes_2.15.1  MASS_7.3-53.1      scales_1.1.1       hms_0.5.3          expm_0.999-6       curl_4.3          
[61] memoise_2.0.0      geosphere_1.5-10   stringi_1.4.6      maptools_1.1-1     desc_1.3.0         e1071_1.7-6       
[67] boot_1.3-27        pkgbuild_1.2.0     rlang_0.4.11       pkgconfig_2.0.3    lattice_0.20-41    tidyselect_1.1.0  
[73] processx_3.5.2     magrittr_2.0.1     R6_2.5.0           generics_0.0.2     DBI_1.1.1          pillar_1.6.0      
[79] haven_2.3.1        foreign_0.8-81     withr_2.4.2        units_0.7-1        modelr_0.1.8       crayon_1.4.1      
[85] KernSmooth_2.23-18 utf8_1.2.1         usethis_2.0.1      grid_4.0.5         readxl_1.3.1       data.table_1.14.0 
[91] blob_1.2.1         callr_3.7.0        reprex_0.3.0       classInt_0.4-3     munsell_0.5.0      sessioninfo_1.1.1

Hello ! I will have a look on this this weekend, could you write here the code used so that I can reproduce the bug ? Thank you very much for you interest in spNetwork !

Hey Jeremy,

Thanks for looking in to this! this is my code:
library(geojsonio) library(geojson) library(rgdal) library(stplanr) library(tidyverse) library(sf) library(spNetwork) library(spdep) library(sp)

cents_oa <- readOGR(file.path("01_DataInput/cents_london_oa/0_downloaded/Output_Areas__December_2011__Population_Weighted_Centroids.shp"))
nn_cents <- closest_points(cents_oa, cents_oa)

Response:

Error in closest_points(cents_oa, cents_oa) : could not find function "closest_points"

You can obtain the centroids from this site:

https://geoportal.statistics.gov.uk/datasets/b0c86eaafc5a4f339eb36785628da904_0?geometry=-18.831%2C50.524%2C14.545%2C55.163

Great, thank you,

I am just a little bit puzzled , what do you want to do here? Do you want to find the closest neighbour of each point in the SpatialPointDataFrame cents_oa? To do so, do you want to use euclidean distance or network distance? In the second case, you will need a SpatialLineDataFrame representing the roads in your study area. In the first case, it is not necessary to use spNetwork, but a good old nearest neighbour search like :

require(fractal)
cents_oa$OID <- 1:nrow(cents_oa)
coords<- data.frame(coordinates(cents_oa))
coords$OID <- cents_oa$OID
neighbors <- findNeighbors(coords, n.neighbor = 1)

I you want to use a road network, let me know, I could give you some code here to do it.

Indeed, nearest neighbour. Thank you Jeremy (!), I was not aware of fractal.

Would you mind giving me the code including the network-based search? Atm I was after Euclidean since that was obvious to me with closest_points. Thanks again in advance, appreciate it!

There is a lot of package for R, do not worry if you do not know one ;-).

With spNetwork, there is currently no dedicated function to find the nearest neighbour of an observation on a network, but it is possible to find it by first creating a spatial neighbouring matrix, and then extracting for each feature its nearest neighbour. Here is a reproductible example with the datasets included in the package.

library(spNetwork)

# loading the data
networkgpkg <- system.file("extdata", "networks.gpkg",package = "spNetwork", mustWork = TRUE)
mtl_network <- rgdal::readOGR(networkgpkg,layer="mtl_network", verbose=FALSE)
eventsgpkg <- system.file("extdata", "events.gpkg", package = "spNetwork", mustWork = TRUE)
bike_accidents <- rgdal::readOGR(eventsgpkg,layer="bike_accidents", verbose=FALSE)

# for each observation in bike_accidents, finding the neighbours within a 3000m radius (on network)
listw <- network_listw(bike_accidents,
                       mtl_network,
                       maxdistance=3000,
                       line_weight = "length",
                       dist_func = 'identity', # I use here the identity function to keep the network distances
                       matrice_type='W', grid_shape = c(2,2))

# and then extracting for each observation its nearest neighbour
neighbours <- sapply(1:length(listw$neighbours), function(i){
  listw$neighbours[[i]][listw$weights[[i]] == min(listw$weights[[i]])][[1]]
})

Thus, you will obtain a vector with the indices of the nearest observation for each row in bike_accidents.
If a big network is used, it could be great to use the multicore version (network_listw.mc) and a finer grid (with higher values in grid_shape).
If it is ok for you, I will close this issue

Wonderful! Thank you so much. Feel free to close the issue.

Perfect !

for completness, a new function has been added to the package today : network_knn, that will perform k-nearest neighbour search on a network without extra-code.