I am working with polygons and I need to create concentric buffers every ten kilometers until I reach a distance of 70 kilometers, in this sense I want only the 10 kilometers rings without the polygon that generated the buffer.

I want something like this: enter image description here I wanted to do a loop, because I have to do it for several shapefiles or a lapply.

I have eight minas sahpes and for each of them I will have to make the seven buffers (from ten to 70 kilometers)

this code works but would like to do a loop:


buff_min10km<- gBuffer(minas, width=10000, byid = TRUE)
buff_min20km<- gBuffer(minas, width=20000, byid = TRUE)
buff_min30km<- gBuffer(minas, width=30000, byid = TRUE)
buff_min40km<- gBuffer(minas, width=40000, byid = TRUE)   
buff_min40km<- gBuffer(minas, width=40000, byid = TRUE)
buff_min50km<- gBuffer(minas, width=50000, byid = TRUE)
buff_min60km<- gBuffer(minas, width=60000, byid = TRUE)
buff_min70km<- gBuffer(minas, width=70000, byid = TRUE)

After taht I take out the center:

ring10km<- gDifference(buff_min10km, minas)    
ring20km <- gDifference(buff_min20km, buff_min10km, byid = TRUE)    
ring30km <- gDifference(buff_min30km, buff_min20km, byid = TRUE)    
ring40km <- gDifference(buff_min40km, buff_min30km, byid = TRUE)    
ring50km <- gDifference(buff_min50km, buff_min40km, byid = TRUE)
ring60km <- gDifference(buff_min60km, buff_min50km, byid = TRUE)
ring70km <- gDifference(buff_min70km, buff_min60km, byid = TRUE)

I tired this but didnt work :

bufferring<-seq(10000, 70000, by=10000)

outerBuffer<-function(x, dist){
 buff<-gBuffer(x, width = dist - 1, byid = T)

for (l in 1:length(bufferring) ){

Give me this error:

Error in gBuffer(x, width = dist - 1, byid = T) : 
length(width) == n is not TRUE 

You did not provide minas so I do not really know if this code will work as you wish. In any case, you can try something like the following:

First, create your names. You can do it either like that:

buff_labs <- paste0("buff_min", seq(10,70, by=10),"km")

Or using magrittr's forward pipes:

buff_labs <- seq(10,70, by=10) %>% paste0("buff_min", .,"km")

Then, create your buffering:

buffering<-seq(10000, 70000, by=10000)
names(buffering) <- buff_labs

Use mapply() to loop:

buffers <- mapply(FUN = rgeos::gBuffer,
                 width = buffering,
                 MoreArgs = list(spgeom =minas, byid=TRUE),
                 SIMPLIFY = FALSE, 
                 USE.NAMES = TRUE)

Then make a list with your centers:

centers <- c(minas, buffers[1:(length(buffers)-1)])

And calculate the rings:

rings <-mapply(FUN = rgeos::gDifference,
             spgeom1 = buffers,
             spgeom2 = centers,
             SIMPLIFY = FALSE, 
             USE.NAMES = TRUE) 

You got yourself all your buffers in a nice list in which each element is accessible by name and position. To plot them you just have to loop along the list.

Hope it helps


If you want to save them we can use, for example, the function rgdal::writeOGR(). To be able to use this function, objects must be SpatialPolygonsDataFrames. Thus, we proceed as follows:

First, we create as many data.frames as buffers. Here I'm using the labels we gave to the buffer to create a data.frame per label:

data.aux <- lapply(buff_labs, as.data.frame, col.names = "buffer")

Then we use sp::SpatialPolygonsDataFrame() function to link SpatialPolygons and dataframes looping everything with mapply()

rings.spdf <- mapply(sp::SpatialPolygonsDataFrame,

Last, we save each buffer as ESRI shapefile in the HDD using:

mapply(FUN = rgdal::writeOGR,
       dsn = paste0("PathToYourFolder", buff_labs, ".shp"),
       layer = buff_labs,
       MoreArgs = list(
         driver = "ESRI Shapefile",
         encoding = "utf8",
         overwrite_layer = TRUE),
       USE.NAMES = TRUE)

Note that encoding is set as UTF8 and overwrite as TRUE. Check out that the value of those parameters is really compatible with what you want to accomplish

| improve this answer | |
  • Thank you. It worked, but I need to save it in my directory as a shapefile (SpatialPolygonDataFrame) , because I'll use them to extract pixels values from a raster. I would like to share my data here, but I don't know how to do it. – Kledson Lemes Apr 8 at 17:23
  • If hepls here is a link with my data: drive.google.com/drive/folders/… – Kledson Lemes Apr 8 at 18:35
  • Do not worry. I'll edit my answer so you can save them as ESRI shapefiles – davidnortes Apr 8 at 18:39
  • thank you very much!!!! it worked very well .... You saved me hours of work. – Kledson Lemes Apr 8 at 18:56
  • I'm glad it helped! :) – davidnortes Apr 8 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.