# Are there default functions for discrete uniform distributions in R?

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)


PDF:

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


CDF:

pdu<-function(x,k) ifelse(x<1,0,ifelse(x<=k,floor(x)/k,1))

-
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. –  Joseph Hsieh Oct 25 '10 at 0:47
+1 for the implementation of the PDF and CDF! :) –  nico Oct 25 '10 at 6:46
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)) –  G. Jay Kerns 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)/(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)

-

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))


EDIT

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)

-
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. –  csgillespie Oct 25 '10 at 8:30
@csgillespie: nicely spotted, I updated my answer :) –  nico Oct 25 '10 at 8:32
Couldn't you use ceiling(runif(1000, min=-1, max=100))? –  gung Aug 2 '12 at 13:26