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
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
-
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.– Bernd V.2021年07月12日 10:30:09 +00:00Commented Jul 12, 2021 at 10:30
-
Hi, I added an edit with the buffering partElio Diaz– Elio Diaz2021年07月12日 13:10:58 +00:00Commented Jul 12, 2021 at 13:10