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.

asked Jul 11, 2021 at 22:30

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
answered Jul 12, 2021 at 0:07
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. Commented Jul 12, 2021 at 10:30
  • Hi, I added an edit with the buffering part Commented Jul 12, 2021 at 13:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.