2
$\begingroup$

How to generate distribution in R, members of which are inside bounds and mean with SD are fixed?

I just need a distribution which will fit in the supported criteria. This will be used for simulating results from other study for comparison with data I have.

I need something like this:

rBootstrap<-function(n,mean,sd,lowerBound,upperBound){
   ...
}

which result of d <- rBootstrap(100,50,10,30,100)) had

min(d) $\approx$ 30, max(d) $\approx$ 100, mean(d) $\approx$ 50, sd(d) $\approx$ 10.

The best result I had achieved is:

rBootstrap<-function(n,mean,sd,lowerBound,upperBound){
    data <- rnorm(n,mean,sd)
    return(data)
}
summary(rBootstrap(100,50,10,30,100))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  26.18   41.27   47.29   48.43   55.06   71.82

and it is very far from desired. I had tried several others but without success.

Is it possible to do this at all and in R in particular?

$\endgroup$
  • 1
    $\begingroup$ Could you provide additional criteria that would help narrow down the possible distributions? What, for instance, is the reason for "generating" this distribution? $\endgroup$ – whuber Sep 1 '11 at 13:57
  • $\begingroup$ @whuber Updated question following your comment. $\endgroup$ – Yuriy Petrovskiy Sep 1 '11 at 18:43
7
$\begingroup$

There typically is more than 1 distribution with the given set of parameters (mean, sd, upper and lower boundaries). So there are several ways of doing this.

Since you are looking for a continuous distribution that is bounded, Wikipedia suggests among others, the beta distribution.

If I recall correctly, there is a parametrisation of the beta-distribution in terms of the mean and variance. So if you transform your boundaries to [0,1] and apply the same transformation to your mean and sd, then generate data with the beta distribution (rbeta), which guarantees that your data will be within [0,1], and transform back, you should get reasonable results.

BTW: why do you call this bootstrap? Apparently, you're just trying to sample from a distribution?

Edit: Yurij used the suggestions from this answer and the comments, resulting in this function:

rBootstrap<-function(n,mean,sd,lowerBound,upperBound){
    range <- upperBound - lowerBound
    m <- (mean-lowerBound) / range #mapping mean to 0-1 range
    s <- sd / range #mapping sd to 0-1 range
    a <- (m^2 - m^3 - m*s^2)/s^2 #calculating alpha for rbeta 
    b <- (m-2*m^2+m^3-s^2+m*s^2)/s^2 #calculating beta for rbeta
    data <- rbeta(n,a,b)  #generating data
    data <- lowerBound + data * range #remaping to given bounds
    return(data)
}
$\endgroup$
  • 3
    $\begingroup$ This shows how to find the parameters of the beta-distribution in terms of the mean and variance $\endgroup$ – Henry Sep 1 '11 at 16:11
  • $\begingroup$ @Nick Done this using rbeta as you said with the help of link supported by @Henry. Would you mind if I add function I made to your answer? $\endgroup$ – Yuriy Petrovskiy Sep 1 '11 at 18:31
  • $\begingroup$ @Nick: Added code. The only thing I missed is "non-centrality parameter" for rbeta, as I do not fully understand in`s meaning and how it could be calculated. $\endgroup$ – Yuriy Petrovskiy Sep 1 '11 at 18:51
2
$\begingroup$

If you want to generate data from a distribution determined by your data, but not a straight bootstrap, then look at the logspline package for R. You can set a minimum and a maximum and have the general shape of the distribution follow from the data (would give similar mean and sd, but not guarenteed to be exact). You can then generate new random observations from the fitted distribution using the rlogspline function.

$\endgroup$
  • $\begingroup$ Thank you for the idea. The solution with rbeta really has problem with reaching bounds if mean is far from bounds. I had tried to look at logspline package, but could not understand how to apply it. As far as I had understood rlogspline is used for "scaling" the distribution to arbitrary size. It is good, but how to setup initial distribution to use with logspline function to fit the given criteria? $\endgroup$ – Yuriy Petrovskiy Sep 1 '11 at 19:47
  • 2
    $\begingroup$ The logspline package is for if you have data (not just the summaries) and want to fit a distribution to the data and generate new observations from that distribution. I suggested it in case the summaries that you posted were from some actual data that you have. If you have only the summaries then, while possible, this will be much harder using logspline and there are not simple tools for this approach. $\endgroup$ – Greg Snow Sep 1 '11 at 20:15
1
$\begingroup$

Sadly this won't do you much good in R, but since I think it's faintly on topic for the general question, this link on my blog: http://confounding.net/2010/12/01/randomly-generating-a-truncated-normal-distribution/ is the code to generate normally distributed data with fixed upper and lower bounds.

$\endgroup$
0
$\begingroup$

Found a prepackaged solution here. There is a distributions called "truncated" which has upper and/or lower limit. One of them is truncated normal distribution.

There are a couple of functions designed to sample from a truncated normal distribution:

  • rtruncnorm(100, a=-Inf, b=5, mean=3, sd=2) in the truncnorm package
  • rtnorm(100, 3, 2, upper=5) in the msm package
$\endgroup$
  • 2
    $\begingroup$ Truncated distribution is not a specific kind of distribution (like Normal or Beta), but any distribution can be truncated. We call distribution "truncated" if it has got restricted range (see en.wikipedia.org/wiki/Truncated_distribution) $\endgroup$ – Tim May 19 '15 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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