Generating random points inside raster boundary using R?

Rasters are always rectangles. Your shape on the far left is padded with no-data cells, so the extent object will be a rectangle that contains the visible data and the NA padding.

To sample randomly from data cells only, you could try something like

# which cells are not NA? These ones:
notna <- which(!is.na(values(raster)))

# grab 20 cell index numbers at random
samp <- sample(notna, 20, replace = FALSE)

# and their values
sampdata <- raster[samp]

# and their location coordinates
samplocs <- xyFromCell(raster, samp)

# convert to a data frame
samp <- as.data.frame(cbind(samplocs, samp, sampdata))
names(samp) <- c('x', 'y', 'index', 'value')

# and optionally, a spatial object, in sf or sp
library(sp)
samp_sp <- samp
coordinates(samp_sp) <- ~x + y
crs(samp_sp) <- CRS('+init=epsg:4326')

library(sf)
samp_sf <- st_as_sf(as.data.frame(samp), coords = c('x', 'y'), crs = 4326)

This does preclude sampling more than once from any given cell, and all sample points will be in the exact middle of cells, which may or may not matter to you.


Suppose a Landsat band:

r <- raster('~/path/to/LC80160442016191LGN00_cfmask_conf.tif')

plot(r)

enter image description here

I recommend to compute NA cells (to determine raster's edges) and convert them to lines (because polygonize is a very slow process in R). After this, convert them to polygon and use it to sample points:

lin <- rasterToContour(is.na(r))

library(sf) # to call st_* functions

pol <- as(st_union(st_polygonize(st_as_sf(lin))), 'Spatial') # st_union to dissolve geometries

pts <- spsample(pol[1,], 2000, type = 'random')

plot(r)
plot(pts, add = T, col = 'red')

enter image description here

Tags:

Random

R

Raster