1

I have a directory of shape-files with identical data scheme, which I like to read and combine into one layer.

Reading in:

library(sf)
library(dplyr)
# create list of file names from directory
names.shapes <- list.files(path=PATH_TO_DIRECTORY,pattern = "\\.shp$") 
#read layers into list of layers
lstShapes <- lapply(paste(PATH_TO_DIRECTORY,names.shapes,sep="/"), st_read) 
#adding file names to list items
names(lstShapes) <- names.shape

I could now merge the layers from the list with

result <- bind_rows(lstShapes)

Unfortunately, the layers are of mixed geometry types. There is a point layer among several polygon layers. Of course I could "manually" select this point layer, and e.g. by buffering convert it onto a polygon layer as well, but I am searching for a programatical way to select/filter the non-polygon features from the simple feature data frame resulting from bind_row and only buffer those to get an all-polygon layer I can export as a GIS-layer

So far, I can't find a way to filter and buffer the point features within the sf data frame.

1 Answer 1

0

If I understand correctly, there are point and polygon shapefiles in your path (shp can't have two geometry types). You may query with st_geometry_type after having all layers bound together with bind_rows.

library(sf)
library(dplyr)
nc = st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE)

nc_centr = st_centroid(nc) # just to have a point layer to bind

nc_mixed = rbind(nc, nc_centr) %>% mutate(g_type = st_geometry_type(.))

# check geometry types of the layer
unique(nc_mixed$g_type)
[1] MULTIPOLYGON POINT       

nc_filtered = nc_mixed %>% filter(g_type == "MULTIPOLYGON")

# check again
unique(nc_filtered$g_type)
[1] MULTIPOLYGON

then you may use st_buffer() for the only polygon layer. You may do the filtering in a single step with filter(st_geometry_type(.) == "MULTIPOLYGON") and overwrite unnecessary objects.

Edit

I think it's easier to separate both data frames and buffer the point layer, since the other way would involve an if else statement and assigning the geometry column; in this data set we have to first transform to a projected coordinate system with st_transform, you say yours is already projected.


nc_buffered_points = nc_mixed %>% st_transform(32617) %>%
  filter(g_type == "POINT") %>%
  st_buffer(5)

nc_polygons = nc_mixed %>% st_transform(32617) %>%
  filter(g_type != "POINT") 

nc_all = rbind(nc_buffered_points, nc_polygons)

# and we see points have become polygons:
unique(st_geometry_type(nc_all))
[1] POLYGON      MULTIPOLYGON


2
  • Thank you very much for you help! Great how to add the geometry type to the data. As I am not very comfortable still with the piping process (doing stuff in R too rarely), I am still confused about how to buffer the points in nc_mixed with, e.g. 5m (my data is metric) within a pipe, leaving the polygon features untouched. Would be very grateful for a more clear advise.
    – Bernd V.
    Commented Jul 12, 2021 at 10:30
  • Hi, I added an edit with the buffering part
    – Elio Diaz
    Commented Jul 12, 2021 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.