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) 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. Thanks in advance, Alex
How to draw 4 random weights that sum up to 1?
5 messages · Alexander Engelhardt, Uwe Ligges, David Winsemius +1 more
You probably want to generate data from a Dirichlet distribution. There are some functions in packages that will do this and give you more background, or you can just generate 4 numbers from an exponential (or gamma) distribution and divide them by their sum.
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 Alexander Engelhardt > Sent: Monday, October 10, 2011 10:11 AM > To: r-help > Subject: [R] How to draw 4 random weights that sum up to 1? > > 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) > > 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. > > Thanks in advance, > Alex > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.
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) 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.
Thanks in advance, Alex
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
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
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 > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.