# Sample points randomly within raster cells in R

I would like to generate one random point for each cell in a raster, while excluding NAs. I can use `sampleRandom` however this just gives me the centroid of each cell:

``````    library(raster)
ras <- raster(nrows = 3, ncols = 3)
v <- c(1,2,NA,4,NA,NA,7,8,9)
ras[] <- v
plot(ras)
samp <- sampleRandom(ras, ncell(ras), xy = TRUE, sp=TRUE, na.rm = TRUE)
points(samp)
``````

I want to generate random points so that I can then extract data from multiple other raster layers which are not necessarily the same resolution (and therefore the centroid isn't representative so I'd rather have a random point).

I am currently doing it using `spsample` on an spdf, but I'd rather avoid having to use shapefiles if possible as the memory requirements are getting too big.

Just randomly move each point within its cell. (This is a very fast operation.) In the image, the gray circles mark the original centers while the red dots show where they have been moved to. ``````dx <- diff(c(xmin(ras), xmax(ras))) / ncol(ras) / 2 # Half of horizontal width
dy <- diff(c(ymin(ras), ymax(ras))) / nrow(ras) / 2 # Half of vertical width
xy <- coordinates(samp)                             # 2-column matrix of coordinates
n <- nrow(xy)                                       # Number of sample points
xy <- xy + c(runif(n, -dx, dx), runif(n, -dy, dy))  # Add random changes
points(xy, pch=21, bg="red")                        # Plot the new sample
``````
• I did think about this but, honestly at the time, was just too lazy to recommend a code solution. Thanks for working this through. Dec 21, 2016 at 22:41

It is giving you the centroid of each cell because you are setting n to the same as the number of cells in the raster (ncells(ras)), therefore not taking a sample. Set n to something sensible and you will get a sample.

Your logic of a full sample, with random locations in each cell, seems like overkill even when sampling rasters of a different resolution. The key word here is "sample" you do not need the population of this raster to act as a sample of another raster!

The only real way I can think of to do this in R is coercing the raster to a SpatialGridDataFrame object, which represents grid cells as polygons and iterate through non NA cells. Although, it sounds like you have tried something like this already. I am not clear where a shapefile comes into play but, I believe that you are stuck here.

• Yes I'm really only using the raster to define the boundary of where I want the points to fall. The problem is I want one point for every cell (which for instance represents 10km^2 area) which is not `NA`, hence setting number of points to `ncell(ras)`. Since I have the rasters already creating spdf or SpatialGridDataFrame seems a resource heavy extra step I was hoping wasn't necessary
– Emma
Dec 21, 2016 at 10:09
``````library(raster)
ras <- raster(nrows = 3, ncols = 3)
v <- c(1,2,NA,4,NA,NA,7,8,9)

ras[] <- v
plot(ras)
res(ras)

ras_fine <- raster(nrows = 9, ncols = 9) #finer resolution raster
ras<-resample(ras,ras_fine,method='ngb')
plot(ras)

samp_strat.rand<- sampleStratified(ras, 1, xy = TRUE, sp=TRUE, na.rm = TRUE)

plot(ras)
points(samp_strat.rand)
``````

This can be accomplished by using resample() to change the resolution of the coarse resolution layer to the finer layer. Be sure to use method = 'ngb' for nearest neighbor. Then perform a stratified random sample with 1 value/ strata.