Most standard distributions in R have a family of commands - pdf/pmf, cdf/cmf, quantile, random deviates (for example- dnorm, pnorm, qnorm, rnorm).

I know it's easy enough to make use of some standard commands to reproduce these functions for the discrete uniform distributions, but is there already a preferred built-in family of functions for modeling discrete uniform distributions in R that I'm unaware of?


As nico wrote, they're not implemented in R. Assuming we work in 1..k, those functions should look like:

For random generation:

rdu<-function(n,k) sample(1:k,n,replace=T)


ddu<-function(x,k) ifelse(x>=1 & x<=k & round(x)==x,1/k,0) 


pdu<-function(x,k) ifelse(x<1,0,ifelse(x<=k,floor(x)/k,1))
| cite | improve this answer | |
  • 4
    $\begingroup$ Thanks. I think it would be handy to have built-in functions (with min and max paraemters ala the unif family). It's a bit ugly to have to add function definitions into scripts just to use the discrete uniform distributions the way you would use other standard distributions. The builtin functions also deal with error handling (for example - if parameters aren't integers) and are optimized for speed. $\endgroup$ – Joseph Hsieh Oct 25 '10 at 0:47
  • 2
    $\begingroup$ Nice answer. And for the quantiles we can do something like qdu <- function(p, k) ifelse(p <= 0 | p > 1, return("undefined"), ceiling(p*k)) $\endgroup$ – user1108 Oct 25 '10 at 15:24

Here is the code for the discrete uniform distribution in the range [min, max], adapted from mbq's post:

dunifdisc<-function(x, min=0, max=1) ifelse(x>=min & x<=max & round(x)==x, 1/(max-min+1), 0)
punifdisc<-function(q, min=0, max=1) ifelse(q<min, 0, ifelse(q>=max, 1, (floor(q)-min+1)/(max-min+1)))
qunifdisc<-function(p, min=0, max=1) floor(p*(max-min+1))
runifdisc<-function(n, min=0, max=1) sample(min:max, n, replace=T)
| cite | improve this answer | |

The CRAN Task View: Probability Distributions page says:

The discrete uniform distribution can be easily obtained with the basic functions.

I guess something on the lines of this should do:

a <- round(runif(1000, min=0, max=100))


As csgillespie pointed out, this is not correct...

a <- ceiling(runif(1000, min=0, max=100))

will work though (note that the example will generate values between 1 and 100, not 0 and 100)

| cite | improve this answer | |
  • 4
    $\begingroup$ This isn't correct for the edge cases. To see this, try running the following command: table(round(runif(10000, min=0, max=2))) It's clearly not discrete uniform. $\endgroup$ – csgillespie Oct 25 '10 at 8:30
  • $\begingroup$ @csgillespie: nicely spotted, I updated my answer :) $\endgroup$ – nico Oct 25 '10 at 8:32
  • 1
    $\begingroup$ Couldn't you use ceiling(runif(1000, min=-1, max=100))? $\endgroup$ – gung - Reinstate Monica Aug 2 '12 at 13:26

Your Answer

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