[R] User-defined random variable
Matthias Kohl
Matthias.Kohl at uni-bayreuth.de
Sun May 1 10:45:31 CEST 2005
Achim Zeileis wrote:
>On Sat, 30 Apr 2005, Peter Dalgaard wrote:
>
>
>
>>Paul Smith <phhs80 at gmail.com> writes:
>>
>>
>>
>>>Dear All
>>>
>>>I would like to know whether it is possible with R to define a
>>>discrete random variable different from the ones already defined
>>>inside R and generate random numbers from that user-defined
>>>distribution.
>>>
>>>
>>Yes. One generic way is to specify the quantile function (as in
>>qpois() etc.) and do qfun(runif(N)).
>>
>>
>
>If the support discrete but also finite, you can also use sample(), e.g.
>
> sample(myset, N, replace = TRUE, prob = myprob)
>
>Z
>
>
>
>>--
>> O__ ---- Peter Dalgaard Blegdamsvej 3
>> c/ /'_ --- Dept. of Biostatistics 2200 Cph. N
>> (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
>>~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
>>
>>______________________________________________
>>R-help at stat.math.ethz.ch mailing list
>>https://stat.ethz.ch/mailman/listinfo/r-help
>>PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>>
>>
>>
>
>______________________________________________
>R-help at stat.math.ethz.ch mailing list
>https://stat.ethz.ch/mailman/listinfo/r-help
>PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>
>
Hi,
one can also use our R package "distr" to generate discrete random
variables. The subsequent code provides a function which generates an
object of class "DiscreteDistribution" based on a finite support "supp".
If "prob" is missing all elements in "supp" are equally weighted.
Matthias
# generating function
DiscreteDistribution <- function(supp, prob){
if(!is.numeric(supp))
stop("'supp' is no numeric vector")
if(any(!is.finite(supp))) # admit +/- Inf?
stop("inifinite or missing values in supp")
len <- length(supp)
if(missing(prob)){
prob <- rep(1/len, len)
}else{
if(len != length(prob))
stop("'supp' and 'prob' must have equal lengths")
if(any(!is.finite(prob)))
stop("inifinite or missing values in prob")
if(!identical(all.equal(sum(prob), 1,
tolerance = 2*distr::TruncQuantile), TRUE))
stop("sum of 'prob' has to be (approximately) 1")
if(!all(prob >= 0))
stop("'prob' contains values < 0")
}
if(length(usupp <- unique(supp)) < len){
warning("collapsing to unique support values")
prob <- as.vector(tapply(prob, supp, sum))
supp <- sort(usupp)
len <- length(supp)
}else{
o <- order(supp)
supp <- supp[o]
prob <- prob[o]
}
if(len > 1){
if(min(supp[2:len] - supp[1:(len - 1)]) < distr::DistrResolution)
stop("grid too narrow --> change DistrResolution")
}
rfun <- function(n){
sample(x = supp, size = n, replace = TRUE, prob = prob)
}
intervall <- distr::DistrResolution / 2
supp.grid <- as.numeric(matrix(
rbind(supp - intervall, supp + intervall), nrow = 1))
prob.grid <- c(as.numeric(matrix(rbind(0, prob), nrow = 1)), 0)
dfun <- function(x){ stepfun(x = supp.grid, y = prob.grid)(x) }
cumprob <- cumsum(prob)
pfun <- function(x){ stepfun(x = supp, y = c(0, cumprob))(x) }
qfun <- function(x){ supp[sum(cumprob<x)+1] }
return(new("DiscreteDistribution", r = rfun, d = dfun, p = pfun,
q = qfun, support = supp))
}
# some examples
supp <- rpois(20, lambda=7) # some support vector
D1 <- DiscreteDistribution(supp = supp) # prob is missing
r(D1)(10) # 10 random numbers of Distribution D1
support(D1) # support
d(D1)(support(D1)) # pdf
p(D1)(5) # cdf
q(D1)(0.5) # quantile (here: median)
plot(D1) # plot of pdf, cdf and quantile
D2 <- lgamma(D1) # apply member of group generic "Math"
plot(D2)
D3 <- D1 + Binom(size=10) # convolution with object of class
"DiscreteDistribution"
plot(D3)
D4 <- D1 + Norm() # convolution with object of class "AbscontDistribution"
plot(D4)
More information about the R-help
mailing list