[R] Generate random vectors (continuous number) with a fixed sum
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Thu Apr 24 22:19:45 CEST 2025
BTW, my function could be a little more efficient: it can only possibly
have lowlimit > highlimit on the first coordinate, so that test could
come out of the loop.
Duncan Murdoch
On 2025-04-24 4:05 p.m., Duncan Murdoch wrote:
> On 2025-04-24 1:33 p.m., Brian Smith wrote:
>> Hi Rui,
>>
>> This code is able to generate absolutely correct random sample vector
>> based on the applicable constraints.
>>
>> I have one question though.
>>
>> If I understood the R code correctly then, the first element is
>> drawing random number from Uniform distribution unconditionally,
>> however drawing of sample point for the second element is conditional
>> to the first one. Therefore if we have large vector size instead of
>> current 2, I guess the feasible region for the last few elements will
>> be very small.
>>
>> Will that be any problem? does there any algorithm exist where all
>> (n-1) elements would be drawn unconditionally assuming our vector has
>> n elements?
>
> The answer could be yes or no depending on what you mean by "drawn
> unconditionally".
>
> If you mean "draw a coordinate that depends on previous coordinate
> draws, and always accept it" then the answer is yes. You would modify
> the limits of each draw depending on previous draws and the limits on
> upcoming draws.
>
> If you mean "draw each coordinate independently of previous draws", then
> then answer is no, you can't do that except in a few very special cases.
>
> Here's an example function:
>
> rfixedsum <- function(n, sum, lower, upper) {
> dim <- length(lower)
> stopifnot(dim == length(upper), length(sum) == 1)
>
> result <- matrix(NA, n, dim)
> currentsums <- 0
>
> for (i in 1:(dim-1)) {
> # The highest following values could be is sum(upper[(i + 1):dim))
> # The lowest they could be is sum(lower[(i + 1):dim)
> lowlimit <- pmax(lower[i], sum - currentsums - sum(upper[(i + 1):dim]))
> highlimit <- pmin(upper[i], sum - currentsums - sum(lower[(i +
> 1):dim]))
> if (any(lowlimit > highlimit))
> stop("sampling is impossible")
> newvals <- runif(n, lowlimit, highlimit)
> currentsums <- currentsums + newvals
> result[,i] <- newvals
> }
> result[, dim] <- sum - currentsums
> result
> }
>
>
> Duncan Murdoch
More information about the R-help
mailing list