Skip to content

Instantly share code, notes, and snippets.

@jlehtoma
Last active December 31, 2015 02:59
Show Gist options
  • Save jlehtoma/7924643 to your computer and use it in GitHub Desktop.
Save jlehtoma/7924643 to your computer and use it in GitHub Desktop.
library(maptools)
library(rgdal)
library(rgeos)
setwd("~/type1")
species <- 'speciesX1'
list_shp <- list.files(path=species, pattern="*.shp", full.names = TRUE,
recursive = TRUE, include.dirs = FALSE)
shp_objects <- lapply(list_shp, function(x) {readOGR(dsn=x,
layer=ogrListLayers(x))})
# Inspect the SpatialPolygonsDataFrame (SPDF) objects visually
spplot(shp_objects[[1]], "mrgid")
spplot(shp_objects[[2]], "mrgid")
# See the row names (IDs)
lapply(shp_objects, function(x) row.names(x@data))
# Overlapping row names (IDs) won't do as the SPDFs cannot be merged (by rbind)
# if IDs are not unique. Use lapply and generate an unique id string on the fly
# (taken from: http://bit.ly/19afgCh)
set.seed(1234)
shp_objects <- lapply(shp_objects, function(x) {
new.id <- paste0(x@data$id, sprintf("%03d", round(runif(1, 1, 999)),0))
spChFIDs(x, new.id)
})
# Check the IDs again
lapply(shp_objects, function(x) row.names(x@data))
# Merge the two SPDF
merged_shp_objects <- do.call("rbind", shp_objects)
# Check visually
spplot(merged_shp_objects, "mrgid")
# Some of the polygons (areas) are the same in the two original SPDFs.
# Check the attribute data
merged_shp_objects@data
# E.g. Alboran sea (mrgid=3324) is present in both. Make a spatial union based
# on a common ID-value (mrgid)
union_polygons <- unionSpatialPolygons(merged_shp_objects,
IDs=merged_shp_objects@data$mrgid)
# Check how many polygons are present in the original merge
nrow(merged_shp_objects)
# How many polygons are present after merge
length(union_polygons)
# unionSpatialPolygons returns a SpatialPolygons object, but we want to retain
# the original attribute data as well. Get only the unique rows fromt the
# original attribute data
attribute_data <- unique(merged_shp_objects@data)
# Row names (IDs) need to match the IDs in union_polygons
rownames(attribute_data) <- attribute_data$mrgid
# Create a new SPDF
final_shp_object <- SpatialPolygonsDataFrame(Sr=union_polygons,
data=attribute_data)
# Checks
nrow(final_shp_object)
spplot(merged_shp_objects, "mrgid")
@johannesbjork
Copy link

For setting the number (and names) of fields to three, i.e. name, id and mrgid. Edited it, since different type of shapefiles have different fields. (Insert after row 10)

set.seed(1234)
  for(i in seq_along(shp_list)){
    # EEZ
    if('objectid' %in% colnames(shp_list[[i]]@data)==T){
      shp_list[[i]]@data <- subset(shp_list[[i]]@data, select=-c(objectid, country, sovereign, remarks, sov_id, eez_id, iso_3digit, date_chang  ,area_m2, longitude ,latitude))
      shp_list[[i]]@data['id']<-paste0(shp_list[[i]]@data$id,shp_list[[i]]@data$iso_3digit)
      colnames(shp_list[[i]]@data)[colnames(shp_list[[i]]@data) == 'eez'] <- 'name'
    }else{
      # IHO + EEZ (e.g. Mexican part of the North Pacific Ocean, 25569)
      if('iho_id' %in% colnames(shp_list[[i]]@data)==T){
        shp_list[[i]]@data<-subset(shp_list[[i]]@data, select=-c(objectid_1, iho_sea, iho_id, iho_mrgid, country, sovereign, sov_id, eez, eez_mrgid, longitude, latitude, area_m2))
        colnames(shp_list[[i]]@data)[colnames(shp_list[[i]]@data) == 'marregion'] <- 'name'
        colnames(shp_list[[i]]@data)[colnames(shp_list[[i]]@data) == 'eez_id'] <- 'id'
        shp_list[[i]]@data['id']<-paste0(shp_list[[i]]@data$id, paste0(sprintf("%1s", sample(LETTERS,1)),sprintf("%1s", sample(LETTERS,1))))
        shp_list[[i]]@data <- shp_list[[i]]@data[,c(1,3,2)]
      }else{
        # MEOW (ecoregion, e.g. Bahamian 21980)
        if('eco_code' %in% colnames(shp_list[[i]]@data)==T){
          shp_list[[i]]@data<-subset(shp_list[[i]]@data, select=-c(lat, long, placetype))
          colnames(shp_list[[i]]@data)[colnames(shp_list[[i]]@data) == 'ecoregion'] <- 'name'
          colnames(shp_list[[i]]@data)[colnames(shp_list[[i]]@data) == 'eco_code'] <- 'id'
          shp_list[[i]]@data['id']<-paste0(shp_list[[i]]@data$id, paste0(sprintf("%1s", sample(LETTERS,1)),sprintf("%1s", sample(LETTERS,1))))
          shp_list[[i]]@data <- shp_list[[i]]@data[,c(2,1,3)]

        }
      }
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment