2

I need to erase different vector layers(shapefiles) using R, but I am not sure how to do it in a fast way.

I have 10 different shapefiles and a basemap (also shapefile) that I need to erase my vectors from (I need something equivalent to using the "difference" tool in QGIS).

I know how to do it manually, using the ms_erase tool, but I was wondering if there is an easy way of iterating this process:

output1 <- ms_erase(basemap, vector1)
output2 <- ms_erase(output1 , vector2)
output3 <- ms_erase(output2 , vector3)

I loaded the vectors using the st_read function, so their class in R is data.frame.

4
  • You may try first to rbind() all your erasing layers and the use that ms_erase or st_difference from sf
    – Elio Diaz
    Commented Apr 19, 2022 at 12:53
  • 1
    I would suggest the same as @ElioDiaz but you might want to ms_dissolve your combined files after rbind and before ms_erase if the shapes are complex or overlap. Installing Node.js and using sys = TRUE in ms_erase can also boost performance quite a bit if your first attempt crashes or takes too long.
    – Sandy AB
    Commented Apr 19, 2022 at 15:43
  • I agree with @SandyAB; if your layers have different column names, dplyr::bind_rows() will work better
    – Elio Diaz
    Commented Apr 19, 2022 at 16:01
  • Which package does the ms_erase function come from? Why aren't you using the st_difference function from sf? Can you read all your shapefiles into a list of objects and loop over that list?
    – Spacedman
    Commented Apr 19, 2022 at 21:43

1 Answer 1

1

I would read your 10 shapefiles into a list object so that you can easily combine them using do.call.

s <- do.call("rbind", lapply(list.files(getwd(), "shp$")[-1], st_read))

Note; if s does not result in an sf object you may have to wrap it in st_as_sf. The index "[-1]" is a illustration of removing a specific file. I am assuming that your "basemap" is in the same directory so, it should not be read into the list. You can figure out the position(s) of shapefiles to omit by just looking at the results of list.files(getwd(), "shp$"). Using indexing you can read in specific files eg., [c(1,3,5)] would read in the first, third and fifth files in the list.files vector.

Once you have the features that you want erased, then read in the base map and difference the features (not tested).

st_erase <- function(x, y) { st_difference(x, st_union(st_combine(y))) }
  b <- st_read(list.files(getwd(), "shp$")[1])
    e <- st_erase(b, s) 

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.