0
votes

I have a list of SpatialPolygons I created using lapply and the raster::buffer function. I would like to convert the files in the list back to a list of SpatialPolygonsDataFrame objects. I tried the answer provided here (although note my issue is slightly different because I would like to end up with a LIST of SpatialPolygonsDataFrame objects): R - SpatialPolygonsDataFrame from a list of SpatialPolygons, but i don't know how to get unique IDs for each object in the list. When I apply that code, I get the following error msg:

#Getting polygon IDs
IDs <- sapply(list_of_SPols, function(x)
 slot(slot(x, "polygons")[[1]], "ID"))

#Checking
length(unique(IDs)) == length(list_of_SPols) #output = [1] FALSE

#Making SpatialPolygons from list of polygons
Spol <- SpatialPolygons(lapply(list_of_SPols,
                            function(x) slot(x, "polygons")[[1]]))

#output = Error in validObject(res) : 
  #invalid class “SpatialPolygons” object: non-unique Polygons ID slot 
  #values

My SpatialPolygons list elements have unique index values, but when I check the output of the IDs object created above, a subset of it looks like this:

#[1] "1" "1" "1" "1" "1" "1" "1"....

So all list elements have the same IDs. So I think what I need to do is create unique IDs equal to the index numbers?

How do I do this, then how do I go on to create a list of SpatialPolygonsDataFrame objects?

1
you have been asking several questions over the past days; but you are not really following the rules. You need to provide a self-contained example. That is, include some code and data generated by code, or using the examples. A part of the answer to your questions is that you can use match.ID = FALSE. But there is more that you do wrong, I think, but it is hard to answer without data.Robert Hijmans

1 Answers

1
votes

One of the reasons why it is important to show data is that you might be asking the wrong question. If you want to use raster::buffer with a SpatialPolygonsDataFrame and keep that object type, you should use the option dissolve=FALSE

library(raster)
p <- shapefile(system.file("external/lux.shp", package="raster"))
b1 <- buffer(p, .1)
class(b1)
#[1] "SpatialPolygons"

b2 <- buffer(p, .1, dissolve=FALSE)
class(b2)
#[1] "SpatialPolygonsDataFrame"

That probably solves your problem. To answer your question about creating SpatialPolygonDataFrame objects from a list of SpatialPolygon objects

Example list of SpatialPolygon objects

library(raster)
p <- shapefile(system.file("external/lux.shp", package="raster"))
s <- as(p, 'SpatialPolygons')
x <- lapply(seq(1,12,3), function(i) s[i:(i+2),])

Presumably you already have data.frame objects you want to match, but I just create them here. This gives an error

z <- lapply(x, function(i) SpatialPolygonsDataFrame(i, data.frame(id=1:length(i)))) 
#Error in SpatialPolygonsDataFrame(i, data.frame(id = 1:length(i))) : 
#row.names of data and Polygons IDs do not match

This works

z <- lapply(x, function(i) SpatialPolygonsDataFrame(i, data.frame(id=1:length(i)), match.ID = FALSE))   

In most cases, you would want to combine the objects. To keep track of them, you could do

zz <- lapply(1:length(x), function(i) SpatialPolygonsDataFrame(x[[i]], data.frame(id=rep(i, length(x[[i]]))), match.ID = FALSE))    
sp <- bind(zz)