I was wondering if there was a more straight-forward (i.e. "integrated") way to do a
dplyr::full_join()-type operation on two sf objects.
st_join() function performs a "spatial join", and the dplyr
*_join() functions for sf objects expect
x to be an sf object, and
y to be a dataframe. What I am really looking for, is a function that merges the two sf objects (kind of like an
rbind() operation) while keeping all the data attached to the geometries (i.e. introducing NAs when the data is missing).
Therefore, when joining two A and B objects, the resulting object C should have
nrow(C) == nrow(A) + nrow(B), and have as many columns as necessary to contain all the original data (and one single geometry column).
This is an operation that I imagine is pretty common, and I would encounter this task often when dealing with OpenStreetMap data.
See for example this code, that uses a
# get libraries around Brisbane from OSM library(osmdata) lib <- getbb("Brisbane, Queensland") %>% opq() %>% add_osm_feature(key = "amenity", value = "library") %>% osmdata_sf() # extract relevant data: # polygons pol <- lib$osm_polygons # points library(dplyr) pnt <- lib$osm_points %>% # only keep libraries described as a point, not part of polygon filter(!is.na(name)) # convert polygons to centroids library(sf) cnt <- st_centroid(pol) # merge points and centroids, keeping all variables all_libs <- st_as_sf(data.table::rbindlist(list(pnt, cnt), fill = TRUE)) # visualise them library(tmap) tmap_mode("view") tm_shape(all_libs) + tm_dots()
data.table::rbindlist() solution was found in this
sf issue: https://github.com/r-spatial/sf/issues/798#issuecomment-405157853
And the general non-spatial join issue is discussed here: https://github.com/r-spatial/sf/issues/239
My example works well, but I was wondering if I was missing something and there actually was a function in
sf designed for that kind of operation?
My session info:
R version 3.6.1 (2019-07-05) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 18.04.3 LTS Matrix products: default BLAS: /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3 LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so locale:  LC_CTYPE=en_AU.UTF-8 LC_NUMERIC=C LC_TIME=en_AU.UTF-8  LC_COLLATE=en_AU.UTF-8 LC_MONETARY=en_AU.UTF-8 LC_MESSAGES=en_AU.UTF-8  LC_PAPER=en_AU.UTF-8 LC_NAME=C LC_ADDRESS=C  LC_TELEPHONE=C LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C attached base packages:  stats graphics grDevices utils datasets methods base other attached packages:  dplyr_0.8.3 sf_0.8-0 tmap_2.3-1 osmdata_0.1.1.007 loaded via a namespace (and not attached):  tidyselect_0.2.5 purrr_0.3.2 lattice_0.20-38 htmltools_0.3.6  viridisLite_0.3.0 yaml_2.2.0 XML_3.98-1.20 rlang_0.4.1  e1071_1.7-2 later_0.8.0 pillar_1.4.2 glue_1.3.1  DBI_1.0.0 sp_1.3-1 RColorBrewer_1.1-2 stringr_1.4.0  rgeos_0.5-2 rvest_0.3.4 raster_3.0-7 htmlwidgets_1.3  leafsync_0.1.0 codetools_0.2-16 httpuv_1.5.2 crosstalk_1.0.0  curl_4.2 class_7.3-15 Rcpp_1.0.2 KernSmooth_2.23-16  xtable_1.8-4 promises_1.0.1 classInt_0.4-1 lwgeom_0.1-7  leaflet_2.0.2 jsonlite_1.6 mime_0.7 packrat_0.5.0  digest_0.6.22 stringi_1.4.3 shiny_1.3.2 tmaptools_2.0-2  grid_3.6.1 rgdal_1.4-6 tools_3.6.1 magrittr_1.5  tibble_2.1.3 dichromat_2.0-0 crayon_1.3.4 pkgconfig_2.0.3  data.table_1.12.4 xml2_1.2.2 lubridate_1.7.4 assertthat_0.2.1  httr_1.4.1 rstudioapi_0.10 R6_2.4.0 units_0.6-4  compiler_3.6.1