I have a shapefile that contains roughly 200,000 features, each with a unique Zone Code. Within each of these features I would like to randomly place n points. A separate dataset contains a list of the unique Zone Codes and the number of random points required. The end result I am after is a list of Zone Code's with a set of unique x,y coordinates for however many points are required for each feature.

I need to do this in R and have some code that does the job. However, it is not very quick and takes almost a day to complete. I am looking for any help in speeding up the process.

Here is an example of the code I am using (with a shapefile and dataset that contains 196 features):


download.file("https://dl.dropboxusercontent.com/u/27869346/Zone_ZIP.zip", "Zone_ZIP.zip")
Zone_Shape <- readOGR(".", "ZONE_CD")

Zone_Data <- read.csv("https://dl.dropboxusercontent.com/u/27869346/ZONE_DATA.csv",header=TRUE)

Points_All <- NULL
for(i in 1:nrow(Zone_Data)){
Zone_Shape_Single <- Zone_Shape[Zone_Shape@data$ZONE_CD %in% Zone_Data[i,1], ]
Points <- spsample(Zone_Shape_Single, Zone_Data[i,2], type="random", iter=10)
Points_DF <- cbind(Zone_Data[i,1],as.data.frame(Points))
Points_All <- rbind(Points_All, Points_DF)
  • The files do not exist anymore in your Dropbox. Jun 26, 2018 at 18:25

1 Answer 1


For starters: instead of that rbind, make Points_All a list, and assign each Points_DF result to it with Points_All[[i]] <- Points_DF. Then do a single rbind of all the list elements at the end. Have a look at this example gist.

You should also join your csv to the attribute table of your shp, so that your sample numbers become another attribute. Then you can ditch the if loop and just iterate over polygons. Look at the documentation for merge, your code should look something like x@data <- merge(x@data, csv, by = 'common_field', all.x = T, all.y = F).

  • thanks for your answer, it's definitely a better way of doing it than my effort. Your answer has made me think that my current approach is never going to be that efficient. I would need to find something along the lines of running 'spsample' simultaneously on all features and their different values to get the time saving I am after.
    – Chris
    Mar 6, 2017 at 22:33
  • have a look at package 'foreach' maybe @Chris - haven't had call to use it myself but it looks helpful.
    – obrl_soil
    Mar 7, 2017 at 9:04

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.