# How to create randomly points within polygons for each row of a dataframe matching a Polygon ID with R

My question is similar to this post, but because there are no "perfect" answer and above all no reproducible example I open this question.

I have a "SpatialPolygonsDataFrame" and a data frame. Both have a variable of common factors. I would like to generate a random point for each observation of the data frame within the according polygon.

I am starting to learn GIS with R. I read the first chapters of Bivand et al. 2013 but i am still strugling with the basics. I tried with the function from the library(sp) but I am puzzling with the variable n of this function: it's an (approximate) sample size

In my example there are 3 polygons and 30 observations. The common variable is MatchID. I need a SpatialPolygonsDataFrame with 15 points in the first polygons ("abcd"), 10 in the second ("efgh") in 5 in the third ("ijkl"). See

table(df$MatchID)  Example:  library(sp) # Definition of the CRS poly.crs <- CRS("+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs +ellps=WGS84 +towgs84=0,0,0") # Definition of 3 Polygons poly.a <- Polygon((matrix(c(-4.653724,1.2210259,-3.803160, 1.3799638, -3.245480, 0.1665987,-4.666098, 0.1097523, -4.653724, 1.2210259), nrow=5, ncol=2, byrow=T))) poly.b <- Polygon((matrix(c(-5.820343, 2.675320,-5.427519, 3.062975,-4.701119, 2.819967,-4.555540, 1.855489, -5.050758, 1.388308, -5.783673, 1.572882,-5.820343, 2.675320), nrow=7, ncol=2, byrow=T))) poly.c <- Polygon((matrix(c(-3.758639, 2.873654, -3.273958, 3.417311, -2.213099, 2.935320, -1.972031, 1.945992, -3.033510, 1.279312, -3.709359, 1.844633, -3.758639, 2.873654), nrow=7, ncol=2, byrow=T))) # Making a SpatialPolygons polys.a = Polygons(list(poly.a), "pa") polys.b = Polygons(list(poly.b), "pb") polys.c = Polygons(list(poly.c), "pc") Spolys = SpatialPolygons(list(polys.a,polys.b,polys.c), 1:3, proj4string=poly.crs) # Making a SpatialPolygonsDataFrame data.Spolys<- (data.frame(MatchID=c("abcd","efgh","ijkl"), row.names=row.names(Spolys))) Poly <- SpatialPolygonsDataFrame(Spolys, data.Spolys, match.ID = TRUE) ## Data frame that should be converted in a SpatialPointsDataFrame thanks to the variable "MatchID" df <- data.frame( MatchID=c("abcd","abcd","abcd","efgh","efgh","ijkl"), V1 = 1:30, V2 = "a" )  I need a function to generalize the idea below (looking for the matching with the factor) and giving exactly the number of observation I need (and not an approximate random size) spdf.a <- SpatialPointsDataFrame(spsample(Poly[Poly$MatchID=="abcd",], n = nrow(df[df$MatchID=="abcd",]), "stratified"), df[df$MatchID=="abcd",])

• To fix the size of the sample I found an answer. To fix it e.g. to 30: sample(spsample(x,n),30) with n>30
– nebi
Jul 23 '14 at 11:42

After a lot of attempts I have this solution, probably not so clean. Comments, improvements or other way to answer are much welcome!

### Preparing the SpatialPointsDataFrame
spdf <- matrix(as.numeric(NA), nlevels(Poly$MatchID), 1) spdf <- as.list(spdf) ### Sample the coordinate, match it with data in spdf. It creates a list fore each factor of the MatchID ### sample(spsample()) fix the size of the sample for (i in seq(Poly$MatchID))
spdf[i] <- SpatialPointsDataFrame(
sample(spsample(Poly[order(Poly$MatchID)==i,], n = 100, "stratified"),table(df$MatchID)[[i]]),  ### table(df$MatchID)[[i]] is the size of the sample and match the sum of factors in df df[df$MatchID==dimnames(table(df$MatchID))[][i],], ## dimnames(table(df$MatchID))[][i] ### match the value of the selected "factor" to select the rows of the data
proj4string=poly.crs,
match.ID=TRUE)

## Merging together the list to make a SpatialDataFrame
spdf <- do.call("rbind", spdf)

## Plot
plot(Poly[,])