1

I want to generate a raster surface (cost surface) based only on distance from center of extent where the values in the raster cells generate a Weibull distribution. I am interested specifically in the Weibull distribution, but the approach should be flexible enough to be modified to use with other distributions.

Here is some example code:

library(raster)

mat = matrix(data = rep(0,400),nrow=20,ncol=20)
rast = raster(mat,xmn=-10,xmx=10,ymn = -10,ymx=10)
crs(rast) = '+proj=utm +zone=12 +datum=WGS84'
plot(rast)

distFromPt = 1/raster::distanceFromPoints(rast, c(0,0)) 
plot(distrFromPt)

I want to be able to sample from the distrFromPt, such that the values of distrFromPt represent the probability that the cell would be chosen. For example, if the shape and scale parameters were both 1, then sampling 1000 random points should generate a distance histogram that looked like a weibull distribution.

hist(rweibull(1000,1,1),breaks=50)

histogram of weibull

I think the answer is somewhere in turning the values of distFromPt into quantiles, but just can't quite think how to do it.

Update:

Based on @Spacedman recommendations and another posting by @ Spacedman here, I have generated the following code:

library(raster)
mat = matrix(data = rep(0,400),nrow=20,ncol=20)
rast = raster(mat,xmn=-10,xmx=10,ymn = -10,ymx=10)
crs(rast) = '+proj=utm +zone=12 +datum=WGS84'
plot(rast)

distFromPt = 1/raster::distanceFromPoints(rast, c(0,0))
plot(distFromPt)

D = values(distFromPt)
Zw = qweibull(seq(0,1,len = length(rast)),1,1)
ZD = Zw[rank(D)]

values(rast) = ZD/sum(ZD)

hs = res(rast)/2

ptscell = sample(1:length(rast), 1000, prob=rast[], replace=TRUE)

centres = xyFromCell(rast,ptscell)

df = cbind(runif(nrow(centres),centres[,1]-hs[1],centres[,1]+hs[1]),
            runif(nrow(centres),centres[,2]-hs[2],centres[,2]+hs[2]))

pts = SpatialPointsDataFrame(coords = df,proj4string = crs(rast),
                               data = as.data.frame(df))

pts$Dist = pointDistance(pts,c(0,0),lonlat = FALSE, type = "Euclidean")

However, when you map the histogram of the distances, it doesn't look like I am able to recover a Weibull distribution.

hist(pts$Dist)

enter image description here I think that this is because, even though the distant cells have a low probability of being selected, there are so many of them they "overwhelm" the cells close to the centroid that have a high probability, but low number of instances.

6
  • As per the help center please do not include chit chat like statements of appreciation within your posts.
    – PolyGeo
    Commented Dec 14, 2021 at 5:51
  • I've read this a few times but I'm still unsure what you want precisely. Do you want a transformation that will turn whatever you get from the distFromPt raster into something with a distribution broadly similar to a Weibull(a,b)? So any general method for transforming data from its empirical distribution to any other distribution would do?
    – Spacedman
    Commented Dec 14, 2021 at 15:21
  • You are correct that this is not specific to a Weibull distribution. for example, a normal distribution would generate a "donut" of probabilities, depending on the mean, with values near the center lower than distance values near the normal mean. I will edit my question accordingly.
    – user44796
    Commented Dec 14, 2021 at 15:49
  • 1
    Oh, now this is completely different to what I thought you wanted to do. Start again. Express it mathematically in terms of weights and distributions. I think you want a surface S(x,y) such that the integral of S(x,y).distance(x,y) ~ Weibull(a,b). But if you wanted that, why didn't you say it?
    – Spacedman
    Commented Dec 14, 2021 at 20:01
  • You are correct. Sorry I did not adequately express what I was looking for.
    – user44796
    Commented Dec 14, 2021 at 20:40

1 Answer 1

0

Suppose I have a vector D of 1000 elements from some distribution I don't know about:

> D = c(rnorm(500), rnorm(500,6,1))
> hist(D)

enter image description here

If I take 1000 points from quantiles of a Weibull(1,1) distribution:

> Zw = qweibull(seq(0,1,len=1000),1,1)
> hist(Zw)

enter image description here

Then I get the values you want. Note how the distribution of D has had no effect on the output distribution.

I suspect the next step you want is to match the values in your raster to values from that Weibull by ranking them so they are ordered, so you have a monotonic transformation from D to Zw.

> ZD = Zw[rank(D)]
> plot(D, ZD)

enter image description here

and this is just an empirical QQ plot of D and ZD. If you knew the distribution of D then you could work out the theoretical QQ plot and use that as a function to compute ZD for each D value, but maybe you don't need that.

What we've sort of done here is first totally flatten the distribution of the data by ranking it 1:N, then taking N values from the target distribution by quantiles (not by random sampling). So this can be done for any source or target distribution (with some diddling for discrete distributions...).

1
  • I think this is close, and I have edited my question to reflect your recommended solution, but sampling from the raster doesn't generate a weibull distribution.
    – user44796
    Commented Dec 14, 2021 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.