Search code examples
rrbindr-spspdf

Aggregating all SpatialPolygonsDataFrame objects from list into one SpatialPolygonsDataFrame


Not looking to editing topology, merely aggregating all polygons into one sp object of type SpatialPolygonsDataFrame (spdf). There is only one polygon per spdf.

Data (dropbox link to data) (filesize 1.1KB) ( dput() not appropriate in this instance):

list_of_spdf <- unlist(readRDS("data.Rds"))

I get the desired result with:

one_spdf <- rbind(list_of_spdf[1][[1]], list_of_spdf[2][[1]], list_of_spdf[3][[1]], makeUniqueIDs = TRUE)

# when plotting can see two polygons (third object is a repeat for sake of testing)
plot(one_spdf)

Having hundreds of objects (though only one polygon per spdf), I need to do the rbind programatically. So I tried lapply

list_of_spdf <- lapply(list_of_spdf, rbind, makeUniqueIDs = TRUE)

Obviously, this returns a list and therefore not what I'm looking for.

So I wrote a function:

rbindSPDF <- function(lst) {
# Create empty spdf objects  
pol <-
    SpatialPolygonsDataFrame(SpatialPolygons(list()), data = data.frame())
  pols <-
    SpatialPolygonsDataFrame(SpatialPolygons(list()), data = data.frame())
# loop for rbind
  for (i in 1:length(lst)) {
    pol[i] <- lst[i][[1]]
    if (length(pols) == 0) {
      pols <- pol[i]
    } else {
      pols <- rbind(pols, pol[i], makeUniqueIDs = TRUE)
    }
  }
  return(pols)
}

However, when using rbindSPDF:

single_spdf <- rbindSPDF(list_of_spdf)

I get:

Error in as.vector(data) : 
 no method for coercing this S4 class to a vector

Not sure what I'm doing wrong here.

Plus, I'm guessing I probably don't even need to use my own function.

Note: On top of many other packages, I'm using spand rgdal for spatial data and would rather avoid using yet another one due to attaching/detaching time and masking.


Solution

  • To have a programmatical version of

    one_spdf <- rbind(list_of_spdf[1][[1]], 
                      list_of_spdf[2][[1]], 
                      list_of_spdf[3][[1]], 
                      ...
                      makeUniqueIDs = TRUE)
    

    for a very long list in list_of_spdf, would something like the following work?

    # generate list containing list_of_spdf[i][[1]]
    list.df <- lapply(seq_along(list_of_spdf),
                      function(i){list_of_spdf[i][[1]]})
    
    # apply rbind to the list
    one_spdf2 <- do.call("rbind",
                         c(args = list.df, makeUniqueIDs = TRUE))
    
    > all.equal(one_spdf, one_spdf2)
    [1] TRUE
    

    The results seem equivalent on my machine.