I am trying to create a forest inventory plot network to calibrate a lidar dataset to predict forest biometrics. To ensure the plot network represents the full distribution of tree heights present in the lidar coverage, I am using a conditioned Latin Hypercube Sampling approach using the clhs()
function in the "clhs" package. I am using a large random sample of pixels from a canopy height model raster I created as the sample space that will be divided into marginal strata for the conditioned Latin Hypercube Sampling. Following the instruction in the package documentation, I am converting my sampled pixels into a point vector using the "sf" package. However, when I run the clhs::clhs()
routine, I get an error:
Error: Not a matrix.
I am confused by this because the clhs()
documentation specifically mentions that "sf" points are accepted input. If I coerce the data to a matrix using as.matrix()
, I get an error saying that matrices are not accepted as an input. I have also isolated this to the primary input (argument x in clhs()
) by accepting all defaults for the parameterization of the Simulated Annealing algorithm. Is this possibly a bug?
Below is the reproducible example:
##loading necessary packages##
library(clhs)
library(terra)
library(sf)
##For reproducibility##
set.seed(78)
##Creating fake raster of tree heights##
fake_rast<-rast(xmin=-123.5, xmax=123.0, ymin=44.5, ymax=45.0, nrow=200, ncol=200, crs="EPSG:4326")
values(fake_rast)<-rnorm(40000, 35, 10)
##Sampling the raster and converting to sf##
smp<-spatSample(fake_rast, 500, as.points=TRUE, na.rm=TRUE, replace=FALSE) %>% st_as_sf()
##Conditioned Latin Hypercube##
#Accepting all Metropolis-Hastings Defaults and Simulated Annealing Defaults##
clhs.test<-clhs(x=smp, size=n)
#Setting all Metropolis-Hastings Defaults and Simulated Annealing Defaults##
n<-50
mi<-NULL
temp<-100
lc<-10
ol<-0.01
td<-0.9
clhs.test<-clhs(x=smp, size=n, temp=temp, iter=lc*log(ol/temp)/log(td),
obj.limit=ol, tdecrease=td, length.cycle=lc, must.include=mi,
use.cpp=TRUE, simple=FALSE)
Turns out this was as straightforward of any error message as it gets, and had I been thinking logically about the HYPERCUBE part of this method, I would have realized I need multiple dimensions to run a CLHS. Instead I only have one dimension, which would be suited to blocking rather than a latin hypercube. Adding additional fake dimension resolved the error. Reproducible solution below:
##loading necessary packages##
library(clhs)
library(terra)
library(sf)
##For reproducibility##
set.seed(78)
##Creating fake raster of tree heights##
blank<-rast(xmin=-123.5, xmax=123.0, ymin=44.5, ymax=45.0, nrow=200, ncol=200, crs="EPSG:4326")
fake_rast1<-blank
fake_rast2<-blank
fake_rast3<-blank
values(fake_rast1)<-rnorm(40000, 35, 10)
values(fake_rast2)<-rnorm(40000, 25, 5)
values(fake_rast3)<-rnorm(40000, 15, 2)
fake_rast<-c(fake_rast1, fake_rast2, fake_rast3)
##Sampling the raster and converting to sf##
smp<-spatSample(fake_rast, 500, as.points=TRUE, na.rm=TRUE, replace=FALSE) %>% st_as_sf()
#Setting all Metropolis-Hastings Defaults and Simulated Annealing Defaults##
n<-50
mi<-NULL
temp<-100
lc<-10
ol<-0.01
td<-0.9
clhs.test<-clhs(x=smp, size=n, temp=temp, iter=lc*log(ol/temp)/log(td),
obj.limit=ol, tdecrease=td, length.cycle=lc, must.include=mi,
use.cpp=TRUE, simple=FALSE)