[GIS] Sample points randomly within raster cells in R

pointrraster

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.

Best Answer

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.

Figure

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