# How to generate random weights that sum to unity using R? [duplicate]

I am trying to generate random numbers (weights) using Monte Carlo simulation using R. I would like to have 10000 simulation replications, generating weights for 13 variables. I am trying the following code

mcrep = 10000 # Simulation replications n = 13 # number of variables to which we will assign weights weights = rexp(n * mcrep) # Simulate standard exponential data

But I want to add a constraint; each set of weights should sum to one. Could anybody help? (based on this or any other code)

• You may try sampling from the Dirichlet distribution. Aug 3, 2023 at 12:57
• Could you tell us more about what are you going to do with these "weights"? Aug 3, 2023 at 12:59
• Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking.
– Community Bot
Aug 3, 2023 at 13:04
• You could take your initial (positive) weights generated any way you like, then divide each of them by their sum, so the new weights have a sum of $1$ Aug 3, 2023 at 13:39
• Answered (for uniform random values) at stats.stackexchange.com/questions/134241 and Dirichlet values at stats.stackexchange.com/questions/289258. But the question is too vague, because you can generate $13$ (say) random variables according to any distribution you like -- even with different marginals and complicated joint dependencies -- and divide them by their sum, provided only that it assigns zero probability to a sum of zero. Thus, you should be more specific and indicate what properties your random numbers need to have to be suitable for your simulation.
– whuber
Aug 3, 2023 at 14:17

## 2 Answers

The following code produces weights which sum to 1. They are distributed according to a $$\text{Dirichlet}(1_{12})$$ distribution.

mcrep = 10000                                # Simulation replications
n = 13                                       # number of variables to which
# we will assign weights
weights = matrix(rexp(n * mcrep), ncol  = n) # Simulate standard exponential data
weights_unity = t(
apply(weights,
1,
FUN = function(x) {x / sum(x)})
)


An extremely simple method would be to sample 12 (13-1) points from a uniform distribution on $$(0,1)$$. If you just plot these points on the unit interval, it cuts the interval into 13 subintervals. The lengths of these subintervals of course add up to the total length of the unit interval - that is, one.

generate_weights <- function ( nn ) {
cutpoints <- sort(runif(nn-1))
diff(c(0,cutpoints,1))
}

generate_weights(13)
t(replicate(5,generate_weights(13)))