# [R] How to draw 4 random weights that sum up to 1?

Greg Snow Greg.Snow at imail.org
Mon Oct 10 20:45:27 CEST 2011

```As an interesting extension to David's post, try:

M4.e <- matrix(rexp(40000,1), ncol=4)

Instead of the uniform and rerun the rest of the code (note the limits on the x-axis).

With 3 dimensions and the restriction we can plot in 2 dimensions to compare:

library(TeachingDemos)

m3.unif <- matrix(runif(3000),  ncol=3)
m3.unif <- m3.unif/rowSums(m3.unif)

m3.exp  <- matrix(rexp(3000,1), ncol=3)
m3.exp  <- m3.exp/rowSums(m3.exp)

dev.new()
triplot(m3.unif)

dev.new()
triplot(m3.exp)

now compare the 2 plots on the density of the points near the corners.

--
Gregory (Greg) L. Snow Ph.D.
Statistical Data Center
Intermountain Healthcare
greg.snow at imail.org
801.408.8111

> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-
> project.org] On Behalf Of David Winsemius
> Sent: Monday, October 10, 2011 12:05 PM
> To: Uwe Ligges
> Cc: r-help; Alexander Engelhardt
> Subject: Re: [R] How to draw 4 random weights that sum up to 1?
>
>
> On Oct 10, 2011, at 12:44 PM, Uwe Ligges wrote:
>
> >
> >
> > On 10.10.2011 18:10, Alexander Engelhardt wrote:
> >> Hey list,
> >>
> >> This might be a more general question and not that R-specific.
> >> Sorry for
> >> that.
> >>
> >> I'm trying to draw a random vector of 4 numbers that sum up to 1.
> >> My first approach was something like
> >>
> >> a <- runif(1)
> >> b <- runif(1, max=1-a)
> >> c <- runif(1, max=1-a-b)
> >> d <- 1-a-b-c
> >>
> >> but this kind of distorts the results, right?
> >> Would the following be a good approach?
> >>
> >> w <- sample(1:100, 4, replace=TRUE)
> >> w <- w/sum(w)
> >
> > Yes, although better combine both ways to
> >
> > w <- runif(4)
> > w <- w / sum(w)
>
> For the non-statisticians in the audience like myself who didn't know
> what that distribution might "look like" (it being difficult to
> visualize densities on your 3-dimensional manifold in 4-space),  here
> is my effort to get an appreciation:
>
>   M4 <- matrix(runif(40000), ncol=4)
>   M4 <- M4/rowSums(M4)
> # just a larger realization of Ligges' advice
>   colMeans(M4)
> [1] 0.2503946 0.2499594 0.2492118 0.2504342
>   plot(density(M4[,1]))
>   lines(density(M4[,2]),col="red")
>   lines(density(M4[,3]),col="blue")
>   lines(density(M4[,4]),col="green")
>
> plot(density(rowSums(M4[,1:2])))
>
>   plot(density(rowSums(M4[,1:3])))
> plot(density(rowSums(M4[,2:4])))
>
> # rather kewl results, noting that these are a reflecion around 0.5 of
> the single vector densities.
>
> >
> > Uwe Ligges
> >
> >
> >
> >> I'd prefer a general algorithm-kind of answer to a specific R
> >> function
> >> (if there is any). Although a function name would help too, if I can
> >> sourcedive.
>
> --
>
> David Winsemius, MD
> West Hartford, CT
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help